本文以 ES 6.6.0 版本为例进行演示.
1 filter与query示例
1.1 准备测试数据
PUT website/_doc/1
{
"title": "小白学ES01",
"desc": "the first blog about es",
"level": 1,
"post_date": "2018-10-10",
"post_address": {
"country": "China",
"province": "GuangDong",
"city": "GuangZhou"
}
}
PUT website/_doc/2
{
"title": "小白学ES02",
"desc": "the second blog about es",
"level": 3,
"post_date": "2018-11-11",
"post_address": {
"country": "China",
"province": "ZheJiang",
"city": "HangZhou"
}
}
1.2 搜索测试
搜索条件: 搜索博客等级(level)大于等于2, 同时发布日期(post_date)是2018-11-11的博客:
(1) 不使用filter:
GET website/_doc/_search
{
"query": {
"bool": {
"must": [
{ "match": { "post_date": "2018-11-11" } },
{ "range": { "level": { "gte": 2 } } }
]
}
}
}
// 结果信息:
"hits": {
"total": 1,
"max_score": 2.0,
"hits": [
{
"_index": "website2",
"_type": "blog",
"_id": "2",
"_score": 2.0, // 评分为2.0
"_source": {
"title": "小白学ES02",
"desc": "the second blog about es",
"level": 3,
"post_date": "2018-11-11",
"post_address": {
"country": "China",
"province": "ZheJiang",
"city": "HangZhou"
}
}
}
]
}
(2) 使用filter:
GET website/_doc/_search
{
"query": {
"bool": {
"must": {
"match": { "post_date": "2018-11-11" }
},
"filter": {
"range": { "level": { "gte": 2 } }
}
}
}
}
// 结果信息:
"hits": {
"total": 1,
"max_score": 1.0,
"hits": [
{
"_index": "website2",
"_type": "blog",
"_id": "2",
"_score": 1.0, // 评分为1.0
"_source": {
"title": "小白学ES02",
"desc": "the second blog about es",
"level": 3,
"post_date": "2018-11-11",
"post_address": {
"country": "China",
"province": "ZheJiang",
"city": "HangZhou"
}
}
}
]
}
2 filter与query的区别
filter和query一起使用时, 会先执行filter.
2.1 相关度处理上的不同
filter
—— 只根据搜索条件过滤出符合的文档, 将这些文档的评分固定为1, 忽略TF/IDF信息, 不计算相关度分数;
query
—— 先查询符合搜索条件的文档, 然后计算每个文档对于搜索条件的相关度分数, 再根据评分倒序排序.
建议:
- 如果对搜索结果有排序的要求, 要将最匹配的文档排在最前面, 就用query;
- 如果只是根据一定的条件筛选出部分数据, 不关注结果的排序, 就用filter.
2.2 性能上的对比
filter 性能更好, 无排序 —— 不计算相关度分数, 不用根据相关度分数进行排序, 同时ES内部还会缓存(cache)比较常用的filter的数据 (使用bitset <0或1> 来记录包含与否).
query 性能较差, 有排序 —— 要计算相关度分数, 要根据相关度分数进行排序, 并且没有cache功能.
2.3 对比结论
1、 业务关心的、需要根据匹配的相关度进行排序的搜索条件放在query
中;;
2、 业务不关心、不需要根据匹配的相关度进行排序的搜索条件放在filter
中.;