es深入搜索之全文检索
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了es深入搜索之全文检索相关的知识,希望对你有一定的参考价值。
参考技术A 我们之前介绍过结构化搜索的简单使用,接下来,我们来看怎样在全文字段中搜索最相关的文档。全文搜索包括两个最重要的方面:
1. 查询与结果的相关性,并根据相关性对结果进行排名。
2. 分析,将数据转化为有区别的、规范化的的过程。
所有的查询都或多或少的会进行相关度计算,但不是所有的查询都会有分析阶段,文本查询可以分为两个部分:
1. 基于词项的查询,如 term 或 fuzzy 这样的查询是没有分析阶段的。他们对单个词项进行操作。
2. 基于全文的查询,比如match, 它们会先了解字段映射的信息,判断字段是否被分词,是否是日期还是数字等, 再根据映射信息,构建要查询的词项列表,根据列表进行查询。
匹配查询 match 是个核心查询。无论需要查询什么字段, match 查询都应该会是首选的查询方式。使用方式如下:
es执行上列步骤的过程如下:
如果一次只能搜索一个词语,那么全文搜索会不太灵活,幸运的是 match 也支持多词查询 。
以上查询其实先后执行了两次 term 查询,使用 bool 进行包含,然后将结果进行合并返回。
以上查询其实会导致出现不相关的结果,我们只想搜索包含words1 和 words2 的文档,而不是 or 的结果。match 查询还可以接受 operator 操作符作为输入参数,默认情况下该操作符是 or 。
这种操作还是有些不妥,在 and 和 or 中间选择太过绝对,如果用户给出了5个词项,我们想只要满足其中4 个 就表示匹配,match 也提供了 minimum_should_match 参数,他是一个最小匹配参数,我们可以控制满足的词项超过改值则表示匹配,最好是使用百分比,因为你也不知道用户提供了多少个词项。该参数的设置非常灵活,完整的信息参考文档,请看 https://www.elastic.co/guide/en/elasticsearch/reference/5.6/query-dsl-minimum-should-match.html#query-dsl-minimum-should-match
如果我们使用 bool 查询黑色、大屏、手机,其中should 语句匹配得越多表示文档的相关度越高,但是我们想要手机所占的权重比较大,内容包括手机的文档排名靠前,可以使用 boost 设置相对权重,注意是相对权重,默认是1。
在说相关度被破坏的原因之前,我们先看看es对于相关度是如何计算的
es 的相似度算法被定义为检索词频率/反向文档频率, TF/IDF ,包括以下内容:
有时,我们索引了一些文档,然后检索发现有些相关度较低的返回排名靠前?
出现上述原因的情况是因为es由于性能原因,不会计算所有索引该文档的节点的IDF,比如我们索引了10个文档, 其中6个文档中包含 foo ,而由于es是分布式的,一个索引会被分为多个分片,有可能分片一包含的5 个文档,有 4 个包含foo, 而另外一个在分片二中,所以会导致结果有差异。
在实际应用中,不会出现该问题,因为本局和全局的IDF差异会随着文档数量的增加逐渐降低。如果想要自己处理该问题,可以在搜索请求之后增加 ?search_type=dfs_query_then_fetch ,他会使得es先计算各个分片的 IDF, 然后在求出全局的 IDF, 生产环境中不要使用。因为只要有足够的数据就可以使得差异减少。
以上是关于es深入搜索之全文检索的主要内容,如果未能解决你的问题,请参考以下文章
ElasticSearch(es)基于Lucene的搜索服务器