上篇提過query模式除對記錄的篩選以外還對符合條件的記錄進行了評分,即與條件的類似匹配程度。咱們把評分放在後面的博文中討論,這篇咱們只介紹query查詢。spa
查詢能夠分爲絕對值查詢和全文查詢:絕對值查詢是指非text類型字段的查詢,全文查詢通常指對於text字段的查詢。若是須要對text字段進行絕對值查詢的話能夠用fields在text字段下定義一個keyword字段。text類型字段在建索引時會經分詞器處理分解成許多單詞,而後在查詢時查詢目標也會經歷分詞處理後才逐個單詞進行匹配。因此要注意錄入的查詢條件不必定是最終的查詢內容,由於會首先進行分詞處理。code
咱們先看幾個絕對值查詢例子:regexp
POST /bank/_search { "query" : { "term" : { "state.keyword": "IL" } } } POST /bank/_search { "query" : { "terms" : { "state.keyword": ["IL","WA"] } } } POST /bank/_search { "query" : { "range" : { "age": { "gte" : 20, "lte" : 40 } } } } POST /bank/_search { "query" : { "prefix" : { "address.keyword": "880" } } } POST /bank/_search { "query" : { "wildcard": { "address.keyword": "*Holmes*" } } } POST /bank/_search { "query" : { "regexp": { "address.keyword": ".*Holmes.*" } } }
elastic4s的表達形式以下:blog
val qTerm = search("bank").query(termQuery("state.keyword","IL")) val qTerms = search("bank").query(termsQuery("state.keyword","IL","WA")) val qRange = search("bank").query(rangeQuery("age").gte(20).lte(40)) val qPrefix = search("bank").query(prefixQuery("address.keyword","880")) val qWildcard = search("bank").query(wildcardQuery("address.keyword","*Holmes*")) val qRegex = search("bank").query(regexQuery("address.keyword",".*Holmes.*"))
全文查詢最簡單的例子就是match query 了:索引
POST /bank/_search { "query" : { "match" : { "address" : "holmes"} } } val qMatch = search("bank").query(matchQuery("address","holmes"))
以上是個單字查詢示範。多字全文查詢以下:ci
POST /bank/_search { "query" : { "match" : { "address" : "holmes lane"} } } val qMMatch = search("bank").query(matchQuery("address","holmes lane"))
問題出現了:查詢結果不但有"880 Holmes Lane"還包括了"685 School Lane",這是由於分詞器把"holmes lane" 分解成了"holmes","lane"兩個單字,而多字查詢默認關係是or,只要包含holmes,lane任何一項都符合條件。咱們能夠用and關聯:it
POST /bank/_search { "query" : { "match" : { "address" : { "query": "holmes lane", "operator": "and" } } } } val qMMatchAnd = search("bank").query(matchQuery("address","holmes lane").operator("and"))
如今結果只剩下"880 Holmes Lane"一條了。下面這個query與之有同效:ast
POST /bank/_search { "query" : { "match" : { "address" : { "query": "holmes lane", "minimum_should_match": "100%" } } } } val qMMatchMin = search("bank").query(matchQuery("address","holmes lane").minimumShouldMatch("100%"))
以上例子都是簡單類型的查詢,即單語句查詢。現實中咱們廣泛須要用and,or來結合多種條件造成複合式查詢。最具表明性的也就是boolQuery了。boolQuery的格式以下:class
GET /bank/_search { "query": { "bool": { "must": [ // lastname=duke and gender.keyword = M
{ "match": { "lastname": "duke" }}, { "term": { "gender.keyword": "M" }} ], "must_not": [ // and firstname.keyword != Jackson and city.keyword != Jackson
{ "term": { "firstname.keyword": "Jackson"}}, { "term": { "city.keyword": "Brogan" }} ], "should": [ // or email.keyword = *.cn or age >= 80
{ "wildcard": { "email.keyword": "*.cn" }}, { "range": { "age": {"gte" : 80}}} ], "filter": [ // filter state.keyword in (IL,WA,TA) and balance >= 100000
{ "terms": { "state.keyword": ["IL","WA","TA"] }}, { "range": { "balance": { "gte": 100000 }}} ] } } }
在elastic4s裏這樣表示:email
val qBool = search("bank").query( boolQuery().must( matchQuery("lastname","duke"), termQuery("gender.keyword","M") ).not( termQuery("fistname.keyword","Jackson"), termQuery("city.keyword","Brogan") ).should( termsQuery("state.keyword",Seq("IL","WA","TA")), rangeQuery("balance").gte(100000) ) )
上面例子裏的must,must_no,should,filter各段落能夠單獨或聯合形式任意出如今boolQuery裏。在任何段落裏還能夠嵌入boolQuery, 以下:
GET /bank/_search { "query": { "bool": { "must": [ { "match": { "lastname": "duke" }}, { "term": { "gender.keyword": "M" }} ], "must_not": [ { "term": { "firstname.keyword": "Jackson"}}, { "term": { "city.keyword": "Brogan" }} ], "should": [ { "wildcard": { "email.keyword": "*.cn" }}, { "range": { "age": {"gte" : 80}}} ], "filter": [ { "terms": { "state.keyword": ["IL","WA","TA"] }}, { "range": { "balance": { "gte": 100000 }}}, { "bool" : { "should" : [ {"range" : {"balance" :{"gte" : 1000}}} ] } } ] } } }