2016年12月,咱们开始研究Ambar——一个文档搜索系统。Ambar使用ElasticSearch做为核心搜索引擎。html
在Ambar开发的过程当中,咱们处理了不少与ES相关的问题,咱们想分享咱们获得的宝贵经验。让咱们从每一个搜索系统的一个重要功能开始——高亮显示搜索结果。算法
在任何搜索系统的可用性中,适当的结果高亮显示是最有价值的部分,首先,它为用户提供了关于内部搜索逻辑的必要信息,以及为何显示该结果。此外,它也使咱们可以仅仅经过快速浏览重点而不是下载和浏览整个文档来估计结果。api
由于Ambar是一个文档搜索系统,我说的文档也是指文件,因此它必须处理很是大的文件(就全文搜索而言),大小大于100Mb。本文介绍了在利用ElasticSearch高亮显示大型文档时如何达到高性能。app
Ambar使用ES做为搜索引擎,搜索通过解析的文件/文档内容及其元数据。下面是Ambar在ES中存储一个文档的例子:elasticsearch
{ sha256: "1a4ad2c5469090928a318a4d9e4f3b21cf1451c7fdc602480e48678282ced02c", meta: [ { id: "21264f64460498d2d3a7ab4e1d8550e4b58c0469744005cd226d431d7a5828d0", short_name: "quarter.pdf", full_name: "//winserver/store/reports/quarter.pdf", source_id: "crReports", extension: ".pdf", created_datetime: "2017-01-14 14:49:36.788", updated_datetime: "2017-01-14 14:49:37.140", extra: [], indexed_datetime: "2017-01-16 18:32:03.712" } ], content: { size: 112387192, indexed_datetime: "2017-01-16 18:32:33.321", author: "John Smith", processed_datetime: "2017-01-16 18:32:33.321", length: "", language: "", state: "processed", title: "Quarter Report (Q4Y2016)", type: "application/pdf", text: ".... laaaaaarge text here ...." } }
上面的JSON文档是一个解析后的.pdf文件,里面有财务报告,文件大小约为100Mb。content.text字段包含报告的解析文本,其大小也约为100Mb。ide
让咱们作一个简单的实验。索引1000个文档,如我之前指定的文档,而不定义任何索引调优或自定义映射。而后看看ES会多快地搜索它们,并高亮显示content.text字段中的检索关键字。性能
结果以下:测试
这种结果是不能接受的。任何使用搜索系统的用户都但愿在点击“搜索”按钮后当即获得搜索结果,而不须要等待半分钟就会出现第一个结果。让咱们来看看高亮显示这个缓慢突出的问题并解决它。ui
ES 和 Lucene底层有三种高亮策略可供选择,这是官方文档连接,三种策略以下:搜索引擎
所以,如今你能够猜到为何ES能够开箱即用地对大文档中的检索关键字高亮显示。对于每次命中检索整个文档并从新分析它的性能很是昂贵,尤为是对于大于1Mb的文档。
因为咱们绝对不能使用普通的高亮显示方式,咱们测试了Postings和FVH。最后的选择是FVH,缘由以下:
在FVH测试中,咱们发现了一个很是棘手的问题。它确实解释了match_phrase查询,而不是Lucene的搜索。它只按查询中指定的顺序突出显示令牌,但Lucene的搜索将令牌按任意顺序解释为命中。若是您正在搜索“John Smith”短语,可是文档在其字段中有“Smith John”值,ES将检索该文档做为命中结果,但FVH不会高亮显示它。解决这个问题的办法是短语置换。咱们提交不一样的查询以搜索和高亮显示,Search获取默认查询,高亮显示经过修改源短语中全部单词位置的变化而构建查询。
ES实际上能够处理大型文档,而且仍然可以提供至关好的性能,重要的是正确地设置索引并记住全部与ES相关的问题。