Лучшие практики для поиска в архиве тысяч документов (PDF и / или XML)

Пересмотр зашедшего в тупик проекта и поиск советов по модернизации тысяч «старых» документы и сделать их доступными через Интернет.

Документы существуют в разных форматах, некоторые устарели :(.doc, PageMaker, распечатка (OCR),PDF, так далее.). Имеются средства для переноса документов в «современные». формат, и многие из бумажных копий уже были распознаны в PDF - мы изначально предполагали, что PDF будет окончательным форматом, но мы открыты для предложений (XML?).

После того, как все документы в едином формате, мы хотели бы сделать их содержимое доступным иsearchable via a web interface, Нам нужна гибкость, позволяющая возвращать только те части (страницы?) Всего документа, в которых поиск "ударил". найден (я полагаю, что Lucene /asticsearch делает это возможным?!?) Может ли это быть более гибким, если весь контент был XML? Если да, то как / где хранить XML? Прямо в базе данных или как отдельные файлы в файловой системе? Что насчет встроенных изображений / графиков в документах?

Любопытно, как другие могут подойти к этому. Там нет "неправильно" ответ Я просто ищу как можно больше информации, чтобы помочь нам продолжить.

Спасибо за любой совет.

Ответы на вопрос(3)

Решение Вопроса

В итоге: я буду рекомендоватьElasticSearchНо давайте разберем проблему и поговорим о том, как ее реализовать:

Есть несколько частей к этому:

  1. Extracting the text from your docs to make them indexable
  2. Making this text available as full text search
  3. Returning highlighted snippets of the doc
  4. Knowing where in the doc those snippets are found to allow for paging
  5. Return the full doc

Что может предоставить ElasticSearch:

  1. ElasticSearch (like Solr) uses Tika to extract text and metadata from a wide variety of doc formats
  2. It, pretty obviously, provides powerful full text search. It can be configured to analyse each doc in the appropriate language with, stemming, boosting the relevance of certain fields (eg title more important than content), ngrams etc. ie standard Lucene stuff
  3. It can return highlighted snippets for each search result
  4. It DOESN'T know where those snippets occur in your doc
  5. It can store the original doc as an attachment, or it can store and return the extracted text. But it'll return the whole doc, not a page.

Вы можете просто отправить весь документ в ElasticSearch в виде вложения, и вы получите полнотекстовый поиск. Но точки соприкосновения (4) и (5) выше: знание того, где вы находитесь в документе, и возвращение частей документа.

Хранения отдельных страниц, вероятно, достаточно для ваших целей «где я» (хотя вы могли бы также перейти на уровень абзаца), но вы хотите, чтобы они были сгруппированы таким образом, чтобы документ возвращался в результатах поиска, даже если ключевые слова поиска появляются на разных страницах.

Сначала часть индексации: хранение ваших документов в ElasticSearch:

  1. Use Tika (or whatever you're comfortable with) to extract the text from each doc. Leave it as plain text, or as HTML to preserve some formatting. (forget about XML, no need for it).
  2. Also extract the metadata for each doc: title, authors, chapters, language, dates etc
  3. Store the original doc in your filesystem, and record the path so that you can serve it later
  4. In ElasticSearch, index a "doc" doc which contains all of the metadata, and possibly the list of chapters
  5. Index each page as a "page" doc, which contains:

    • A parent field which contains the ID of the "doc" doc (see "Parent-child relationship" below)
    • The text
    • The page number
    • Maybe the chapter title or number
    • Any metadata which you want to be searchable

Теперь для поиска. Как вы это сделаете, зависит от того, как вы хотите представить свои результаты - по странице или сгруппированы по документу.

Результаты на странице легко. Этот запрос возвращает список соответствующих страниц (каждая страница возвращается полностью), а также список выделенных фрагментов со страницы:

curl -XGET 'http://127.0.0.1:9200/my_index/page/_search?pretty=1'  -d '
{
   "query" : {
      "text" : {
         "text" : "interesting keywords"
      }
   },
   "highlight" : {
      "fields" : {
         "text" : {}
      }
   }
}
'

Отображение результатов, сгруппированных по & quot; doc & quot; с основными моментами из текста немного сложнее. Это нельзя сделать одним запросом, но небольшая группировка на стороне клиента поможет вам в этом. Один подход может быть:

Шаг 1: сделатьтоп-дети-запрос чтобы найти родителя («документ»), чьи дочерние элементы («страница») лучше всего соответствуют запросу:

curl -XGET 'http://127.0.0.1:9200/my_index/doc/_search?pretty=1'  -d '
{
   "query" : {
      "top_children" : {
         "query" : {
            "text" : {
               "text" : "interesting keywords"
            }
         },
         "score" : "sum",
         "type" : "page",
         "factor" : "5"
      }
   }
}

Шаг 2. Соберите «документ» Идентификаторы из вышеупомянутого запроса и введите новый запрос, чтобы получить фрагменты с соответствующей страницы & quot; quot; документы:

curl -XGET 'http://127.0.0.1:9200/my_index/page/_search?pretty=1'  -d '
{
   "query" : {
      "filtered" : {
         "query" : {
            "text" : {
               "text" : "interesting keywords"
            }
         },
         "filter" : {
            "terms" : {
               "doc_id" : [ 1,2,3],
            }
         }
      }
   },
   "highlight" : {
      "fields" : {
         "text" : {}
      }
   }
}
'

Шаг 3. В вашем приложении сгруппируйте результаты вышеупомянутого запроса по документу и отобразите их.

С результатами поиска по второму запросу у вас уже есть полный текст страницы, который вы можете отобразить. Чтобы перейти на следующую страницу, вы можете просто найти ее:

curl -XGET 'http://127.0.0.1:9200/my_index/page/_search?pretty=1'  -d '
{
   "query" : {
      "constant_score" : {
         "filter" : {
            "and" : [
               {
                  "term" : {
                     "doc_id" : 1
                  }
               },
               {
                  "term" : {
                     "page" : 2
                  }
               }
            ]
         }
      }
   },
   "size" : 1
}
'

Или, в качестве альтернативы, укажите «страницу» Документы, состоящие из$doc_id _ $page_num (например, 123_2), тогда вы можете просто получить эту страницу:

curl -XGET 'http://127.0.0.1:9200/my_index/page/123_2

Parent-child relationship:

Обычно в ES (и большинстве решений NoSQL) каждый документ / объект независим - нет реальных отношений. Путем установления отношений между родителем и ребенком между "doc" и «page», ElasticSearch гарантирует, что дочерние документы (то есть «страница») хранятся в том же сегменте, что и родительский документ («документ»).

Это позволяет вам запуститьтоп-дети-запрос который найдет лучшее соответствие & quot; документу & quot; на основе содержания "страниц".

использованиевеснушка или жеRSolr или аналогичный, он обрабатывает большинство основных форматов документов. Они используют Solr / Lucene.

Я создал и поддерживаю приложение, которое индексирует и ищет документы в формате 70k + PDF. Я обнаружил, что необходимо вытащить простой текст из PDF-файлов, сохранить содержимое в SQL и проиндексировать таблицу SQL с помощью Lucene. В противном случае производительность была ужасной.

Ваш ответ на вопрос