🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] # 简介 关系型数据库查询有where语句,可以找到我们想要的数据 filter和这个类似 filter查询能拿到我们想要的数据,查到的数据会缓存在内存中cache缓存 建立测试数据 ~~~ POST /store/products/_bulk {"index":{"_id":1}} {"price":10,"productID":"SD1002136"} {"index":{"_id":2}} {"price":20,"productID":"SD2678421"} {"index":{"_id":3}} {"price":30,"productID":"SD8897573"} {"index":{"_id":4}} {"price":30,"productID":"SD4535233"} ~~~ 查看测试数据 ~~~ GET /store/products/_mget { "ids": ["1","2","3","4"] } ~~~ 查看library的mapping信息 ~~~ GET /store/_mapping ~~~ # 简单过滤查询 ## 最简单filter查询 ~~~ select document from products where price = 20 ~~~ filtered查询价格是20的商品 ~~~ GET /store/products/_search { "query": { "bool": { "filter": { "term": { "price": "20" } } } } } ~~~ 也可以指定多个值 ~~~ GET /store/products/_search { "query": { "bool": { "filter": { "terms": { "price": ["10", "20"] } } } } } ~~~ ~~~ select product from products where productID = "SD4535233" ~~~ ~~~ GET /store/products/_search { "query": { "filtered": { "filter": { "term": { "productID":"SD4535233" } } } } } ~~~ 这个没有命中任何结果 我们看下mapping,发现是有的,是被分析的 查看分析器解析的结果 ~~~ GET /_analyze?text=SD4535233 ~~~ 发现分析的结果是sd4535233 我们删除他,重新建立映射 ~~~ DELETE /store PUT /store { "mappings": { "products":{ "properties": { "productID": { "type": "string", "index": "not_analyzed" } } } } } ~~~ 然后他不被分析,他就不是小写,因为分析的时候,会把他小写,或者分段 ## bool过滤查询,可以做组合过滤查询 ~~~ select product from products where (price = 20 or productID= "SD1002136") and (price != 30); # 查询价格等于20的或者productID为SD1002136的商品,排除价格30元的 ~~~ 类似的,elasticsearch也有and,or,not这样的组合条件的查询方式 格式如下 ~~~ { "bool": { "must":[], "should":[], "must_not":[], } } ~~~ must条件必须满足,相当于and should:条件可以满足也可以不满足,相当于or must_not:条件不需要,相当于not ~~~ GET /store/products/_search { "query": { "bool": { "filter": { "bool": { "should": [ {"term": {"price": 20}}, {"term": {"productID": "SD1002136"}} ], "must_not": { "term": {"price": 30} } } } } } } ~~~ ## 嵌套查询 ~~~ select document from products where productID="SD1002136" OR (productID = "SD4535233" and price = 30); ~~~ ~~~ GET /store/products/_search { "query": { "bool": { "filter": { "bool": { "should": [ {"term": {"productID": "SD1002136"}}, { "bool": { "must": [ {"term": {"productID": "SD4535233"}}, {"term": {"price": "30"}} ] }} ] } } } } } ~~~ 另外一种,and,or,not查询 没有bool,直接使用and, or, not 查询价格即是10元,productID又为SD1002136的结果 ~~~ GET /store/products/_search { "query": { "bool": { "must": [ { "match": { "price": 10 } }, { "match": { "productID": "SD1002136" } } ] } } } ~~~ or 查询价格是10元或productID是SD4535233的一些商品 ~~~ GET /store/products/_search { "query": { "bool": { "should": [ { "match": { "price": 10 } }, { "match": { "productID": "SD4535233" } } ] } } } ~~~ not 查询productID不是SD1002136的商品 ~~~ GET /store/products/_search { "query": { "bool": { "must_not": [ { "match": { "productID": "SD1002136" } } ] } } } ~~~ # range范围过滤 ~~~ select document from products where price between 20 and 40 gt : > 大于 lt : < 小于 gte : >= 大于等于 lte : <= 小于等于 ~~~ ~~~ GET /store/products/_search { "query": { "filtered": { "filter": { "range": { "price": { "gte": 20, "lte": 40 } } } } } } ~~~ # 过滤空和非空 建立测试数据 ~~~ POST /test_index/test/_bulk {"index": {"_id":"1"}} {"tags":["search"]} {"index": {"_id":"2"}} {"tags":["open_source"]} {"index": {"_id":"3"}} {"other_fields":"some data"} {"index": {"_id":"4"}} {"tags":null} {"index": {"_id":"5"}} {"tags":["search",null]} ~~~ 处理null空值的方法 ~~~ select tags from test where tags is not null select tags from test where tags is null ~~~ ~~~ GET /test_index/test/_search { "query": { "filtered": { "filter": { "exists": {"field": "tags"} } } } } ~~~ ~~~ GET /test_index/test/_search { "query": { "filtered": { "filter": { "missing": {"field": "tags"} } } } } ~~~ # cache缓存 elasticsearch在执行带有filter查询时,会打开索引的每个segment文件(Luncene式底层文件),然后去判断里面的文档是否符合filter要求 注意:旧的segment文件不会变,新来的数据会产生新的segment 匹配的结果会用一个大型的BigSet数组来存储,这个数组的值只有0和1 匹配:1 不匹配:0 BigSet值是存在内存里的,而不是硬盘里,所以速度快 开启方式:在filter查询语句后面加`"_cache":true` 注意: Scriptfilters,Geo-filters,Date ranges这样的过滤方式开启cache无意义 exists,missing,range,term和terms查询是默认开启cache的 filter cache缓存执行原理图 ![](https://img.kancloud.cn/ad/d1/add1a4061c0d7dfc6263056b5f7c4c7f_748x259.png) 匹配的结果会放在Bigset这个数组,匹配上就记为1,没匹配上就为0 ![](https://img.kancloud.cn/19/00/1900906f8b63ca17420e593a38acbacf_379x299.png)