区别
在进行query的时候,除了完成匹配的过程,我们实际上在问“这个结果到底有多匹配我们的搜索关键词”。在所有的返回结果的后面都会有一个_score
字段表示这个结果的匹配程度,也就是相关性。相关性越高的结果就越排在前面,相关性越低就越靠后。当两个文档的相关性相同的时候,会根据lucene内部的doc_id
字段来排序,这个字段对于用户是不可见的也不能控制。
而在进行filter的时候,仅仅是在问“这个文档符不符合要求”,这仅仅是一个过滤的操作判断文档是否满足我们的筛选要求,不会计算任何的相关性。比如timestamp
的范围是否在2019和2020之间,status
状态是否是1等等。
在一个查询语句里面可以同时存在query
和filter
,只不过只有query
的查询字段会进行相关性_score
的计算,而filter
仅仅用来筛选。比如在下面的查询语句里面,只有title
字段会进行相关性的计算,而下面的status
只是为了筛选并不会计算相关性。
GET /my_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "Search"
}
}
],
"filter": [
{
"term": {
"state": 1
}
}
]
}
}
}
对于在实际应用中应该用query
还是用filter
需要根据实际的业务场景来看。如果你的产品的搜索只是需要筛选得到最后的搜索结果并不需要Elasticsearch的相关性排序(你可能自定义了其他的排序规则),那么使用filter
就完全能够满足要求并且能够有更好的性能(filter
不需要计算相关性而且会缓存结果);如果需要考虑文档和搜索词的相关性,那么使用query
就是最好的选择。
相关性
上面讲到了在使用query
查询的时候会计算相关性并且进行排序,很多人都会好奇相关性是怎么计算的?
相关性的计算是比较复杂的,详细的文档可以参考下面的介绍:
1.什么是相关性
2.ElasticSearch 使用教程之_score(评分)介绍
3.相关度评分背后的理论
我这里只是做一个简单的介绍。
Elasticsearch的相似度计算主要是利用了全文检索领域的计算标准——TF/IDF(Term Frequency/Inverted Document Frequency)也就是检索词频率和反向文档频率
- TF(检索词频率):检索词在这个字段里面出现的频率越高,相关性越高。比如搜索词出现5次肯定比出现1次的文档相关性更高。
- IDF(反向文档频率):包含检索词的文档的频率越高,这个检索词的相关性比重越低。如果一个检索词在所有的文档里面都出现了,比如中文的
的
,那么这个检索词肯定就不重要,相对应的根据这个检索词匹配的文档的相关性权重应该下降。 - 字段长度:注意这个字段是文档的里面被搜索的字段,不是检索词。如果这个字段的长度越长,相关性就越低。这个主要是因为这个检索词在字段内的重要性降低了,文档就相对来说不那么匹配了。
在复合查询里面,比如bool
查询,每个子查询计算出来的评分会根据特定的公式合并到综合评分里面,最后根据这个综合评分来排序。当我们想要修改不同的查询语句的在综合评分里面的比重的时候,可以在查询字段里面添加boost
参数,这个值是相对于1
来说的。如果大于1
则这个查询参数的权重会提高;如果小于1
,权重就下降。
这个评分系统一般是系统默认的,我们可以根据需要定制化我们自己的相关性计算方法,比如通过脚本自定义评分。
场景
原则上来说,使用查询语句做全文本搜索或其他需要进行相关性评分的时候,剩下的全部用过滤语句
GET /my_index/_search
{
"query": {
"filtered": {
"query": [
{
"match": {
"title": "Search"
}
}
],
"filter": [
{
"term": {
"state": 1
}
}
]
}
}
}
filtered 查询同时接受接受 query 与 filter 。
filtered和filter的区别
es 5.0版本更新后,filtered的查询将替换为bool查询。
filtered是比较老的的版本的语法。现在目前已经被bool替代。推荐使用bool。
标签:检索,查询,filter,文档,elasticsearch,query,相关性 From: https://blog.51cto.com/u_6353447/5886790