ES 23 - 检索和过滤的区别 (query vs. filter)

目录

  • 1 filter与query示例

    • 1.1 准备测试数据
    • 1.2 搜索测试
  • 2 filter与query的区别
    • 2.1 相关度处理上的不同
    • 2.2 性能上的对比
    • 2.3 对比结论

本文以 ES 6.6.5 版本为例进行演示.

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 中.

版权声明

作者: 马瘦风(https://healchow.com)

出处: 博客园 马瘦风的博客(https://www.cnblogs.com/shoufeng)

感谢阅读, 如果文章有帮助或启发到你, 点个[好文要顶??] 或 [推荐??] 吧??

本文版权归博主所有, 欢迎转载, 但 [必须在文章页面明显位置标明原文链接], 否则博主保留追究相关人员法律责任的权利.

原文地址:https://www.cnblogs.com/shoufeng/p/11278046.html

时间: 2024-11-10 15:43:43

ES 23 - 检索和过滤的区别 (query vs. filter)的相关文章

ES的Query、Filter、metric、bucketing使用详解

由于笔者在实际项目仅仅将ES用作索引数据库,并没有深入研究过ES的搜索功能.而且鉴于笔者的搜索引擎知识有限,本文将仅仅介绍ES简单(非全文)的查询API. 笔者原本打算在本文中介绍聚合API的内容,但是写着写着发现文章有点过长,不便于阅读,故将聚合API的内容移至下一篇博客中. 引言 单单介绍理论和API是乏味和低效率的,本文将结合一个实际的例子来介绍这些API.下表是本文数据表的表结构,表名(type)为“student”.注意,studentNo是本表的id,也就是_id字段的值与stude

elasticsearch query 和 filter 的区别

Query查询器 与 Filter 过滤器 尽管我们之前已经涉及了查询DSL,然而实际上存在两种DSL:查询DSL(query DSL)和过滤DSL(filter DSL).过滤器(filter)通常用于过滤文档的范围,比如某个字段是否属于某个类型,或者是属于哪个时间区间* 创建日期是否在2014-2015年间?* status字段是否为success? * lat_lon字段是否在某个坐标的10公里范围内? 查询器(query)的使用方法像极了filter,但query更倾向于更准确的查找.

数据库笔记6:检索,排序检索,过滤数据

insert into products(prod_id,prod_name,pro_price)values('avno1','.5 ton anvil',5.99);insert into products(prod_id,prod_name,pro_price)values('avno2','1 ton anvil',9.99);insert into products(prod_id,prod_name,pro_price)values('avno3','2 ton anvil',14.

Linux中统计,检索和过滤文件内容的命令以及压缩、归档命令(wc,grep,gzip,bzip2,

统计文件内容wc命令 用途: 统计文件中单词数量(Word Count)等信息wc [选项]... 目标文件...常用命令选项-l:统计行数-w:统计单词个数-c:统计字节数 检索和过滤文件内容grep命令 用途: 在文件中查找并显示包含指定字符串的行grep [选项]... 查找条件 目标文件常用命令选项-i:查看时忽略大小写-v:反转查找,输出与查看条件不相符的行查找条件设置要查找的字符串以双引号括起来"^......" 表示以......开头, "......$ &qu

Elasticsearch的DSL之query and filter

在Elasticsearch的DSL中, 有两个概念需要搞清楚, query 和 filter, 对ES的检索效率是很有影响的. 下面就来搞清楚这两个关键字的具体函数. query context: 回答的是这个文档在多大程度上匹配查询语句(How well does this document match this query clause?),会计算出一个分数_score. filter context: 回答的是这个文档与查询语句是否匹配,是 或者 不是(Does this documen

Join语句中的on和where条件过滤的区别

onli的条件先过滤,在笛卡尔乘积join:而where里条件是先笛卡尔乘积join,然后再过滤. inner join两种条件结果一样,left join和right join就有区别了. 参考blog: https://blog.csdn.net/qq_41973536/article/details/81081024 https://www.jb51.net/article/28188.htm https://blog.csdn.net/u012955829/article/details

OSPF路由过滤和LSA过滤的区别,以及实现方法

OSPF中路由与LSA的关系: OSPF是基于链路状态的路由协议,路由隐藏在LSA中.我们知道,OSPF有三张表,邻居表,拓扑表(LSDB),路由表.而路由表,是基于LSDB得来的,在LSDB中挑选到达目的地最好的LSA抽象成路由信息,加入到转发表,形成路由表. 路由过滤: OSPF的路由过滤,是针对计算出的路由进行的过滤,并不会对LSA及LSDB产生影响,LSA仍能泛洪.路由的过滤,只会对本路由器的路由表产生影响,不会对其他路由器的路由产生影响. 路由过滤实现方法: filter-policy

2-3 多线程和多进程的区别

一 谁的开启速度快? 1.在主进程下开启线程 from threading import Thread def work(): print('hello') if __name__ == '__main__': t=Thread(target=work) t.start() print('主线程/主进程') 执行结果如下,几乎是t.start ()的同时就将线程开启了,然后先打印出了hello,证明线程的创建开销极小 hello 主线程/主进程 2.在主进程下开启子进程 from multipr

[PY3]——过滤数据——列表推导、filter()、itertools.compress()

问题 你有一个数据序列,想利用一些规则从中提取出需要的值或者是缩短序列 解决方案 最简单的过滤数据的方法,就是使用列表推导. 使用列表推导的一个潜在缺陷就是如果输入非常大的时候会产生一个非常大的结果集,对内存敏感时可以考虑使用生成器表达式迭代产生过滤元素 在过滤规则比较复杂不便于用简单的列表推导就写出来的情况下,这时可以考虑写成将规则写成一个函数,然后使用内建的 filter() 函数 还有过滤工具 itertools.compress() 列表推导 lst=[1,4,-5,10,-7,2,3,