文档以各种格式存在,一些过时:(.doc,PageMaker,硬拷贝(OCR),PDF等)。资金可用于将文档迁移到“现代”格式,许多硬拷贝已经被OCR化为PDF – 我们最初认为PDF将是最终格式,但我们接受建议(XML?) 。
一旦所有文档都采用通用格式,我们希望通过Web界面提供并搜索其内容。我们希望灵活地只返回整个文档的一部分(页面?),其中发现了一个搜索“hit”(我相信Lucene / elasticsearch使这可能吗?)?如果内容是所有XML,它可能更灵活吗?如果是这样如何/在哪里存储XML?直接在数据库中,还是作为文件系统中的离散文件?在文档中嵌入图像/图形怎么样?
好奇别人可能会这样做。没有“错误”的答案,我只是寻找尽可能多的输入,以帮助我们继续。
感谢任何建议。
这里有几个部分:
>从文档中提取文本,使其可编入索引
>使此文本作为全文搜索
>返回文档的突出显示的代码段
>知道这些代码片段在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”。