可搜索存档数千个文档的最佳做法(pdf和/或xml)

重新审视一个停滞的项目,寻找在现代化成千上万的“旧”文件,并通过网络提供建议。

文档以各种格式存在,一些过时:(.doc,PageMaker,硬拷贝(OCR),PDF等)。资金可用于将文档迁移到“现代”格式,许多硬拷贝已经被OCR化为PDF – 我们最初认为PDF将是最终格式,但我们接受建议(XML?) 。

一旦所有文档都采用通用格式,我们希望通过Web界面提供并搜索内容。我们希望灵活地只返回整个文档的一部分(页面?),其中发现了一个搜索“hit”(我相信Lucene / elasticsearch使这可能吗?)?如果内容是所有XML,它可能更灵活吗?如果是这样如何/在哪里存储XML?直接在数据库中,还是作为文件系统中的离散文件?在文档中嵌入图像/图形怎么样?

好奇别人可能会这样做。没有“错误”的答案,我只是寻找尽可能多的输入,以帮助我们继续。

感谢任何建议。

总之:我将推荐 ElasticSearch,但让我们把问题解决,并谈谈如何实现它:

这里有几个部分:

>从文档中提取文本,使其可编入索引
>使此文本作为全文搜索
>返回文档的突出显示代码
>知道这些代码片段在doc中的位置
用于寻呼
>返回完整的文档

ElasticSearch提供的内容

> ElasticSearch(如Solr)使用Tika从各种各样的doc formats提取文本和元数据
>很显然,它提供了强大的全文搜索。可以配置
以适当的语言分析每个文档,干预,提高某些字段(例如标题内容更重要),ngram等的相关性,即标准Lucene东西
>它可以为每个搜索结果返回highlighted snippets
>它不知道这些代码段出现在您的文档中
>它可以将原始文档存储为attachment,或者它可以存储和返回提取的文本。但它会返回整个文档,而不是一个页面

您可以将整个文档作为附件发送到ElasticSearch,您将获得全文搜索。但是坚持要点是上面的(4)和(5):知道你在文档中的哪个位置,并且返回文档的部分。

存储单个页面可能足以满足您的“我的目的”(虽然您可以等同于段落级别),但是您希望它们以在搜索结果中返回文档的方式进行分组,即使搜索关键字出现在不同的页面

首先索引部分:将您的文档存储在ElasticSearch中:

>使用Tika(或任何你喜欢的)从每个文档中提取文本。将其保留为纯文本,或保留为HTML以保留一些格式。 (忘了XML,不需要它)。
>还提取每个文档的元数据:标题,作者,章节,语言,日期等
>将原始文档存储在文件系统中,并记录路径,以便以后可以提供
>在ElasticSearch中,索引一个“doc”文档,其中包含所有元数据,以及可能的章节列表
>将每个页面指定为“页面”文档,其中包含:

> A parent field,其中包含“doc”文档的ID(请参阅下面的“父子关系”)
>文本
>页码
>可能是章节标题或数字
>您想要搜索的任何元数据

现在搜索。如何做到这一点取决于你想如何展示你的结果 – 按页或按doc分组。

按页结果很容易。此查询返回匹配页面的列表(每个页面都完整返回)以及页面中的突出显示代码段列表:

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

显示按“doc”分组的结果和文本中的突出显示有点棘手。它不能用一个查询,但一个小的客户端分组会得到你。一种方法可能是:

步骤1:执行一个top-children-query,找到其子代(“页面”)与查询最匹配的父代(“doc”):

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:从上述查询中收集“doc”ID,并发出一个查询,以从匹配的“page”文档中获取代码段:

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步:在您的应用程序中,通过doc将上述查询的结果分组并显示它们。

使用第二个查询搜索结果,您已经拥有了可以显示页面的全文。要移动到下一页,您只需搜索它:

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
}
'

或者,给“page”docs一个ID由$ doc_id _ $ page_num(例如123_2),那么你可以只是检索该页:

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

父子关系:

通常,在ES(和大多数Nosql解决方案)中,每个doc /对象是独立的 – 没有真正的关系。通过在“doc”和“page”之间建立父子关系,ElasticSearch确保子文档(即“页面”)存储在与父文档(“doc”)相同的shard上。

这使您能够运行top-children-query,它将根据“页面”的内容找到最匹配的“doc”。

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念