這裏總結一下es徹底映射mysql的搜索語句,但願可以幫到學習es的同窗們。mysql
這裏咱們假設mysql表有7個字段: birthday, name, sex, height, address, province, city. sql
sql:緩存
select * from table where birthday = '2018-05-17' and name = 'xx' and (sex = 1 or height = 183 or address like 'chengdu%')
es的搜索語句有兩種方式學習
方式1: must + shouldspa
{ "query": { "bool": { "must": [ { "term": { "birthday": "2018-05-17" } }, { "term": { "name": "xx" } }, { "bool": { "should": [ { "term": { "sex": 1 } }, { "term": { "height": 1 } }, { "wildcard": { "address": { "wildcard": "chengdu*" } } } ] } } ] } } }
方式2: 用filter + shouldcode
{ "query": { "bool": { "filter": [ { "term": { "birthday": "2018-05-17" } }, { "term": { "name": "xx" } } ], "should": [ { "term": { "sex": 1 } }, { "term": { "height": 1 } }, { "wildcard": { "address": { "wildcard": "chengdu*" } } } ] } } }
sql:ci
select * from (select * from table where birthday > '2018-05-17' and birthday < '2018-05-17' and name = 'xx') where sex = 1 or height = 183
es的搜索語句是:文檔
{ "query": { "bool": { "filter": [ { "range": { "birthday": { "from": "2018-05-17", "include_lower": true, "include_upper": true, "to": null } } }, { "range": { "birthday": { "from": null, "include_lower": true, "include_upper": true, "to": "2018-05-24" } } }, { "match": { "name ": { "query": "xx" // 這裏不該該對應mysql的=, term應該是=. match用到的是es裏面的分詞,但mysql找不到與之匹配的. } } } ], "should": [ { "term": { "sex": 1 } }, { "term": { "height ": 183 } } ] } } }
sql:it
select * from table where birthday = '2018-05-17' and ( (sex = 1 and height = 183) or (province = 'chengdu' or city = 'chengdu'))
es搜索語句:table
{ "query": { "bool": { "filter": [ { "term": { "birthday": "2018-05-17" } } ], "must": { "bool": { "should": [ { "bool": { "must": [ { "term": { "sex": 1 } }, { "term": { "height": 183 } } ] } }, { "multi_match": { // 能夠用should代替 "fields": [ "province", "city" ], "query": "chengdu" } } ] } } } } }
這三種狀況,應該能應對絕大多數的條件查詢場景。
值得注意的filter和query, 因爲filter不包括評分查詢, 因此更快,更穩定,結果容易緩存,但結果可能不許確。 query是評分查詢(scoring queries)不單單要找出 匹配的文檔,還要計算每一個匹配文檔的相關性,計算相關性使得它們比不評分查詢費力的多。同時,查詢結果並不緩存。