1、fileter查询语句
优点:
1、通过filter查询,一样也能拿到我们想要的数据
2、通过filter可以将数据缓存到内存当中,加快下一次的查询速度
#建立测试数据_1
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
#简单过滤查询
#最简单fileter查询
#SELECT document FROM products WHERE price = 20
#filtered 查询价格是20的商品
GET /store/products/_search
{
"query": {
"filtered": {
"match_all": {}
},
"filter": {
"term": {
"price": 20
}
}
}
}
#也可以制定多个值
GET /store/products/_search
{
"query": {
"filtered": {
"filter": {
"terms": {
"price":[ 10,20]
}
}
}
}
}
#SELECT product FROM products WHERE productID = "SD4535233"
GET /store/products/_search{
"query": {
"filtered": {
"filter": {
"term": {
"productID":"SD453233"
}
}
}
}
}
#返回结果为空?为什么呢?查看 mapping,productID的type是string
#查看分析器解析的结果
GET /_analyzer?text=SD4535233
#分析结果显示式将SD4535233变成了 sd4535233,所以讲上面的查询语句的过滤条件改成sd4535233,就可以搜索到了。
如果想SD4535233被搜索到。需要重新建立一个映射,让productID处于not_analyzed模式
DELETE /store
#重新建立一个映射,让productID处于not_analyzed模式
PUT /store
{
"mappings": {
"products": {
"productID": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
#重新导入测试数据
#再次查询
#bool过滤查询,可以做组合过滤查询
#SELECT product FROM products WHERE (price = 20 OR productID = "SD1002136") AND (price !=30)
#查询价格等于20的或者productID为SD4535233的商品,排除价格30元的。
#类似的,Elasticsearch也有and,or,not这样的组合条件的查询方式
#格式如下:
#{
# "bool": {
# "must": [],
# "should":[],
# "must_not": [],
# }
#}
# must: 条件必须满足,相当于and
# should: 条件可以满足可以不满足,相当于or
# must_not:条件不需要满足,相当于not
GET /store/products/_search
{
"query": {
"filterd": {
"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": {
"filtered": {
"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": {
"filtered":{
"filter": {
"and": [
{
"term": {
"price": 10
}
},
{"term": {
"productID": "SD1002136"
}
}
]
},
"query": {
"match_all": {}
}
}
}
}
#or
#查询价格是10元或productID是SD4535233的一些商品
GET /store/products/_search
{
"query": {
"filtered":{
"filter": {
"or": [
{
"term": {
"price": 10
}
},
{"term": {
"productID": "SD1002136"
}
}
]
},
"query": {
"match_all": {}
}
}
}
}
# not
#查询productID不是SD1002136的商品
GET /store/product/_search
{
"query": {
"filtered":{
"filter": {
"not":{
"term": {
"productID": "SD1002136"
}
}
},
"query":{"match_all": {}}
}
}
}
#range范围过滤
#SELECT document FROM product WHERE price BETWEEN 20 AND 40
# gt: > 大于
# lt: < 小于
# gte: >=大于等于
# lte: <=小于等于
GET /store/product/_search
{
"query": {
"filtered": {
"filter":{
"range": {
"price":{
"gt":20,
"lt":40
}
}
}
}
}
}
#过滤空和非空
#建立测试数据_2
POST /test_index/test/_bulk
{"index": {"_id": "1"}}
{"tags":{"search"}}
{"index":{"_id":"2"}}
{"tags":["search","open_source"]}
{"index":{"_id":"3"}}
{"other_field": "some data"}
{"index":{"_id":"4"}}
{"tags": null}
{"index": {"_id":"5"}}
{"tags": ["search",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": {
"filtered": {
"missing":{"field":"tags"}
}
}
}
}
2、cache缓存
Elasticsearch在执行带有filter查询时,会打开索引的每个segment文件(Lucene是底层文件),然后去判断里面的文档是否符合filter要求。
注意:旧的segment文件不会变,新来的数据会产生新的segment
匹配的结果会用一个大型的BigSet数组来存储,这个数组的值只有0 和1
匹配:1
不匹配:0
BigSet值是存在内存里的,而不是硬盘里,所以速度快
开启方式:在filter查询语句后面加"_cache":true
注意:
Script filters,Geo-filters,Date ranges 这样的过滤方式开启cache无意义
exists,missing,range,term和terms查询是默认开启cache的
filter cache缓存执行原理图
Elasticsearch的底层是Lucene,Lucene的索引是由很多个segment组成,在做filter查询的过程中,会把索引里面的每个segment都打开,打开后,和查询条件进行匹配,匹配的结果会放到名为Bigset的数组(Bigset是一个很大的数组,存储在内存中,只有0和1)中,比如说第一个segment和查询条件匹配,则记为1,如果没匹配上就记为0。index中的segment是不会变的,如果有新的segment只会额外的添加,不会更改原来的segment,因此,你之前匹配的结果也是不会变的。那么有了Bigset数组,再做下一次查询的时候,速度就会提高,因为有缓存
网友评论