欢迎投稿

今日深度:

Elasticsearch笔记-过滤查询,elasticsearch笔记

Elasticsearch笔记-过滤查询,elasticsearch笔记


承接上篇文章Elasticsearch笔记-深入查询,本篇文章主要介绍过滤查询

其实准确来说,ES中的查询操作分为2种:查询(query)和过滤(filter)。查询即是之前提到的query查询,它(查询)默认会计算每个返回文档的得分,然后根据得分排序。而过滤(filter)只会筛选出符合的文档,并不计算得分,且它可以缓存文档。所以,单从性能考虑,过滤比查询更快。

换句话说,过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时,应先使用过滤操作过滤数据,然后使用查询匹配数据。

过滤器使用

查询10月之前contents字段包含“ES”的文档

{
    "query": {
        "filtered":{
            "query":{
                "range":{
                    "date":{
                        "lte":"2016-10-01"
                    }
                }
            },
            "filter":{
                "match":{
                    "contents":"ES"
                }
            }
        }   
    }
}

过滤查询包含filtered关键字,里面又包含普通的查询query逻辑和filter 过滤逻辑。运行时先执行过滤语句,后执行普通查询。对比下面只使用了查询的DSL:

{
    "query": {
        "bool":{
            "must":[{
                "range":{
                    "date":{
                        "lte":"2016-10-01"
                    }
                }
            },{
                "match":{
                    "contents":"ES"
                }
            }]
        }       
    }
}

两者返回结果是一样的。

过滤器类型

过滤器类型与查询类型基本相对应,都有范围(过滤)查询、termterms等类型。

term、terms过滤

term、terms的含义与查询时一致。term用于精确匹配、terms用于多词条匹配。不过既然过滤器既然适用于大氛围过滤,term、terms在过滤中使用意义不大。

举例见前面过滤器使用一节

范围过滤(range)

查询16年10月以来所有内容含有“java”的文档,先过滤剩下符合10月的文章,再精确匹配。

{
    "query": {
        "filtered":{
            "query":{
                "match":{
                    "contents":"java"
                }
            },
            "filter":{
                "range":{
                    "date":{
                        "gte":"2016-10-01"
                    }
                }
            }
        }   
    }
}

exists、mising过滤器

exists过滤指定字段没有值的文档

{
    "query": {
        "filtered":{
            "filter":{
                "exists":{
                    "field":"id"
                }
            }
        }   
    }
}

将不返回id字段无值的文档。

missing 过滤器与exists相反,它过滤指定字段有值的文档。

{
    "query": {
        "filtered":{
            "filter":{
                "missing":{
                    "field":"id"
                }
            }
        }   
    }
}

只返回缺少id值的文档,与上次exists过滤结果形成互补。

标识符(ids)过滤器

需要过滤出若干指定_id的文档,可使用标识符过滤器(ids)

{
    "query": {
        "filtered":{
            "filter":{
                "ids":{
                    "values":[1,2,6,7]
                }
            }
        }   
    }
}

需注意的是:指定的标识符是文档的_id,为文档唯一标识。不同于自己指定的id字段。

限定过滤器(limit)

限定过滤器限定单个分片返回的文档数。

还记得 ElasticSearch笔记-基础知识文章最后提到的分页吗?如果你查询10条数据,则每个分片都会返回10条数据,集合后再选出前10条数据。如果使用limit限定过滤器,则可限定每个分片返回文档数。

限定每个分片返回一条数据

{
    "query": {
        "filtered":{
            "filter":{
                "limit":{
                    "value":1
                }
            }
        }   
    }
}

组合过滤器

可以对这些过滤器组合使用,ES中有2类组合过滤器。一类是bool过滤器,一类是andornot过滤器。bool过滤器对应布尔查询(bool),关于两者的区别,详细解释在这里:

关于elasticsearch filter bitset的全部

这里简要说一下:

总结来说,一般情况下用bool过滤器,当遇到位置查询、数值范围、脚本查询时使用and、or、not过滤。

查询日期在16年10月份且文章标题或内容包含“ES“的文档

用SQL表示为

select * from article where date between  '2016-10-01' and  '2016-10-31' and (name like '%ES%' or contents like '%ES%')

使用bool过滤器

{
    "query": {
        "filtered":{
            "filter":{
                "bool":{
                    "should":[{
                        "match":{
                            "name":"ES"
                        }
                    },{
                        "match":{
                            "contents":"ES"
                        }
                    }],
                    "must":{
                        "range":{
                            "date":{
                                "gte":"2016-10-01",
                                "lte":"2016-10-31"
                            }
                        }
                    }
                }
            }
        }   
    }
}

布尔查询也可嵌套布尔查询,如要查询16年10月份内容有关ES的文章或任何时段文章名称与java相关的所有文章。(这里只是举例,不考虑实际情况)
用SQL表示为

select * from article where contents like '%ES%' and date between '2016-10-01' and '2016-10-31' or name like '%java%'
{
    "query": {
        "filtered": {
            "filter": {
                "bool": {
                    "should": [{
                        "bool": {
                            "must": [{
                                "range": {
                                    "date": {
                                        "gte": "2016-09-01",
                                        "lte": "2016-09-30"
                                    }
                                }
                            }, {
                                "match": {
                                    "contents": "js"
                                }
                            }]
                        }
                    }, {
                        "match": {
                            "name": "java"
                        }

                    }]
                }
            }
        }
    }
}

这里解释一下,我们查询的主要用or关系连接,所以使用bool查询的should语句。一边是contents like '%ES%' and date between '2016-10-01' and '2016-10-31' ,另一个为name like '%java%' 前者需嵌套一个bool查询,使用must连接,后者简单使用match即可。

注意这种结构的写法。类似可参考Elasticsearch权威指南-组合过滤

www.htsjk.Com true http://www.htsjk.com/Elasticsearch/34951.html NewsArticle Elasticsearch笔记-过滤查询,elasticsearch笔记 承接上篇文章Elasticsearch笔记-深入查询,本篇文章主要介绍 过滤查询 。 其实准确来说,ES中的查询操作分为2种:查询(query)和过滤(filter)。...
相关文章
    暂无相关文章
评论暂时关闭