Elasticsearch Query DSL備忘(1)(Constant score query和Bool Query)
阿新 • • 發佈:2018-12-30
Query DSL (Domain Specific Language),基於json的查詢方式
1、Constant score query,常量分值查詢,目的就是返回指定的score,一般都結合filter使用,因為filter context忽略score。
GET /customer/_search { "query": { "constant_score": { "filter": { "match": { "addr": "天津,北京" } }, "boost": 5.2 } } } result:返回結果中score都是被指定的5.2 { "took" : 8, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 5.2, "hits" : [ { "_index" : "customer", "_type" : "doc", "_id" : "510221197801023611", "_score" : 5.2,"_source" : { "name" : "王剛", "id" : "510221197801023611", "addr" : "北京市朝陽區未名路109號", "tel" : "13901004491" } }, { "_index" : "customer", "_type" : "doc", "_id" : "51228199001013611", "_score" : 5.2, "_source" : { "name" : "白開心", "id" : "51228199001013611", "addr" : "天津市海港路1021號", "tel" : "13590850990" } } ] } }
2、bool query,布林查詢
Bool查詢對應Lucene中的BooleanQuery,它由一個或者多個子句組成,每個子句都有特定的型別。
- must 返回的文件必須滿足must子句的條件,並且參與計算分值
- filter 返回的文件必須滿足filter子句的條件。但是不會像must一樣參與計算分值
- should 返回的文件可能滿足should子句的條件。bool查詢在query context中,並且有一個must或filter子句,即使沒有一個should查詢匹配,文件也會進行bool匹配。在這種情況下,這些should僅用於影響分數。如果在filter context中,或者沒有must或filter子句,那麼should子句必須和文件匹配,才能匹配bool查詢。這種行為由minimum_should_match 參與決定。
- must_not 返回的文件必須不滿足must_not定義的條件。
官網的例子:
POST _search { "query": { "bool" : { "must" : { "term" : { "user" : "kimchy" } }, "filter": { "term" : { "tag" : "tech" } }, "must_not" : { "range" : { "age" : { "gte" : 10, "lte" : 20 } } }, "should" : [ { "term" : { "tag" : "wow" } }, { "term" : { "tag" : "elasticsearch" } } ], "minimum_should_match" : 1, "boost" : 1.0 } } }
bool查詢案例分解:
第一步:查詢name為“李雲龍”的文件
GET /customer/_search { "query": { "bool": { "must": { "term":{"name.keyword":"李雲龍"} } } } } 返回三個文件: { "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 3, "max_score" : 1.4916549, "hits" : [ { "_index" : "customer", "_type" : "doc", "_id" : "4", "_score" : 1.4916549, "_source" : { "name" : "李雲龍", "id" : "510221197001013611", "addr" : "昆明市滇池路陽光時代1棟1單元", "tel" : "13808712808" } }, { "_index" : "customer", "_type" : "doc", "_id" : "224", "_score" : 1.4916549, "_source" : { "name" : "李雲龍", "id" : "224", "addr" : "天津市陽光路2008號", "tel" : "13908712808" } }, { "_index" : "customer", "_type" : "doc", "_id" : "510221197001013611", "_score" : 1.4916549, "_source" : { "name" : "李雲龍", "id" : "510221197001013611", "addr" : "上海市浦東區華北路8號", "tel" : "13908712808" } } ] } }
第二步:加入過濾條件,只保留id為510221197001013611的文件
GET /customer/_search { "query": { "bool": { "must": { "term":{"name.keyword":"李雲龍"} }, "filter": { "term": { "id": "510221197001013611" } } } } } 返回結果減少到2個文件,並且score相同: { "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 1.4916549, "hits" : [ { "_index" : "customer", "_type" : "doc", "_id" : "4", "_score" : 1.4916549, "_source" : { "name" : "李雲龍", "id" : "510221197001013611", "addr" : "昆明市滇池路陽光時代1棟1單元", "tel" : "13808712808" } }, { "_index" : "customer", "_type" : "doc", "_id" : "510221197001013611", "_score" : 1.4916549, "_source" : { "name" : "李雲龍", "id" : "510221197001013611", "addr" : "上海市浦東區華北路8號", "tel" : "13908712808" } } ] } }
第三步:使用should,判斷addr中必須有昆明市,這種情況下should子句會影響計分
GET /customer/_search { "query": { "bool": { "must": { "term":{"name.keyword":"李雲龍"} }, "filter": { "term": { "id": "510221197001013611" } }, "should": [ {"match": { "addr": "昆明市" }} ] } } } 返回結果中,地址是昆明市的文件score加重 { "took" : 1, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 2, "max_score" : 3.408528, "hits" : [ { "_index" : "customer", "_type" : "doc", "_id" : "4", "_score" : 3.408528, "_source" : { "name" : "李雲龍", "id" : "510221197001013611", "addr" : "昆明市滇池路陽光時代1棟1單元", "tel" : "13808712808" } }, { "_index" : "customer", "_type" : "doc", "_id" : "510221197001013611", "_score" : 1.5720221, "_source" : { "name" : "李雲龍", "id" : "510221197001013611", "addr" : "上海市浦東區華北路8號", "tel" : "13908712808" } } ] } }
第四步:加入must_not排除上海
GET /customer/_search { "query": { "bool": { "must": { "term":{"name.keyword":"李雲龍"} }, "filter": { "term": { "id": "510221197001013611" } }, "should": [ {"match": { "addr": "昆明市" }} ], "must_not": [ {"match": { "addr": "上海" }} ] } } } 只返回一個文件: { "took" : 2, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 3.408528, "hits" : [ { "_index" : "customer", "_type" : "doc", "_id" : "4", "_score" : 3.408528, "_source" : { "name" : "李雲龍", "id" : "510221197001013611", "addr" : "昆明市滇池路陽光時代1棟1單元", "tel" : "13808712808" } } ] } }