Elasticsearch查詢模式
一種是像傳遞URL參數一樣去傳遞查詢語句,被稱為簡單查詢
GET /library/books/_search //查詢index為library,type為books的全部内容
GET /library/books/_search?q=price:10 //查詢index為library,type為books中price等于10的
另一種是DSL語句來進行查詢,被稱為DSL查詢,term和match就屬于DSL
查詢表達式
查詢表達式(Query DSL)是一種非常靈活又富有表現力的查詢語言。Elasticsearch 使用它可以以簡單的
JSON接口來展現Luncene功能的絕大部分。在你的應用中,你應該用它來編寫你的查詢語句。它可以使你的
查詢語句更靈活、更精确、易讀和易調試。
要使用這種查詢表達式,隻需要将查詢語句傳遞給query參數:
GET /_search
{
"query": YOUR_QUERY_HERE
}
空查詢(empty search)-{}-在功能上等價于使用match_all查詢,正如其名字一樣,比對所有文檔:
GET /_search
{
"query": {
"match_all": {}
}
}
查詢語句的結構
一個查詢語句的典型結構:
{
QUERY_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
如果是針對某個字段,那麼它的結構如下:
{
QUERY_NAME: {
FIELD_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}
舉個例子,你可以使用match查詢語句來查詢tweet字段中包含
elasticsearch
的 tweet:
{
"match": {
"tweet": "elasticsearch"
}
}
完整的查詢請求如下:
GET /_search
{
"query": {
"match": {
"tweet": "elasticsearch"
}
}
}
合并查詢語句
查詢語句(Query clauses) 就像一些簡單的組合塊,這些組合塊可以彼此之間合并組成更複雜的查詢。這些語句可以是如下形式:
- 葉子語句(Leaf clauses) (就像
語句) 被用于将查詢字元串和一個字段(或者多個字段)對比。match
- 複合(Compound) 語句 主要用于 合并其它查詢語句。 比如,一個
語句 允許在你需要的時候組合其它語句,無論是bool
比對、must
比對還是must_not
比對,同時它可以包含不評分的過濾器(filters):should
{ "bool": { "must": { "match": { "tweet": "elasticsearch" }}, "must_not": { "match": { "name": "mary" }}, "should": { "match": { "tweet": "full text" }}, "filter": { "range": { "age" : { "gt" : 30 }} } --包含不含評分的過濾器 } }
一條複合語句可以合并 任何 其它查詢語句,包括複合語句,了解這一點是很重要的。這就意味着,複合語句之間可以互相嵌套,可以表達非常複雜的邏輯。
例如,以下查詢是為了找出信件正文包含
business opportunity
的星标郵件,或者在收件箱正文包含
business opportunity
的非垃圾郵件:
{
"bool": {
"must": { "match": { "email": "business opportunity" }},
"should": [
{ "match": { "starred": true }},
{ "bool": {
"must": { "match": { "folder": "inbox" }},
"must_not": { "match": { "spam": true }}
}}
],
"minimum_should_match": 1
}
}
查詢與過濾
(了解查詢和上上個例子中filter)
Elasticsearch 使用的查詢語言(DSL)擁有一套查詢元件,這些元件可以以無限組合的方式進行搭配。這套元件可以在以下兩種情況下使用:過濾情況(filtering context)和查詢情況(query context)。
當使用于 過濾情況 時,查詢被設定成一個“不評分”或者“過濾”查詢。即,這個查詢隻是簡單的問一個問題:“這篇文檔是否比對?”。回答也是非常的簡單,yes 或者 no ,二者必居其一。
-
時間是否在created
與2013
這個區間?2014
-
字段是否包含status
這個單詞?published
-
字段表示的位置是否在指定點的lat_lon
範圍内?10km
當使用于 查詢情況 時,查詢就變成了一個“評分”的查詢。和不評分的查詢類似,也要去判斷這個文檔是否比對,同時它還需要判斷這個文檔比對的有 多好(比對程度如何)。 此查詢的典型用法是用于查找以下文檔:
- 查找與
這個詞語最佳比對的文檔full text search
- 包含
這個詞,也能比對run
、runs
、running
或者jog
sprint
- 包含
、quick
和brown
這幾個詞 — 詞之間離的越近,文檔相關性越高fox
- 标有
、lucene
或者search
标簽 — 标簽越多,相關性越高java
一個評分查詢計算每一個文檔與此查詢的 相關程度,同時将這個相關程度配置設定給表示相關性的字段
_score
,并且按照相關性對比對到的文檔進行排序。這種相關性的概念是非常适合全文搜尋的情況,因為全文搜尋幾乎沒有完全 “正确” 的答案。
最重要的查詢
雖然 Elasticsearch 自帶了很多的查詢,但經常用到的也就那麼幾個,我們對最重要的幾個查詢進行簡單介紹
term查詢
term是代表完全比對,即不進行分詞器分析,文檔中必須包含整個搜尋的詞彙
term查詢對于輸入的文本不分析,是以它将給定的值進行精确查詢。
格式
GET /library/books/_search #這裡是變化的,指定index和type;(比如說index為library,type為books)
{
"query": {
"term": {
"key": "value" #這裡是變化的,比如說查詢title等于elasticsearch的内容
}
}
}
執行個體1:查詢index為library,type為books重title等于elasticsearch的内容
GET /library/books/_search
{
"query": {
"term": {
"title": "elasticsearch"
}
}
}
term查詢被用于精确值比對,這些精确值可能是數字、時間、布爾或者那些not_analyzed的字元串:
{ "term": { "age": 26 }}
{ "term": { "date": "2014-09-01" }}
{ "term": { "public": true }}
{ "term": { "tag": "full_text" }}
terms查詢
terms
查詢和
term
查詢一樣,但它允許你指定多值進行比對。如果這個字段包含了指定值中的任何一個值,那麼這個文檔滿足條件:
{ "terms": { "tag": [ "search", "full_text", "nosql" ] }}
和
term
查詢一樣,
terms
查詢對于輸入的文本不分析。它查詢那些精确比對的值(包括在大小寫、重音、空格等方面的差異)
match查詢
match和term的差別是,match查詢的時候,elasticsearch會根據你給定的字段提供合适的分析器,而term查詢不會有分析器分析的過程
match查詢相當于模糊比對,隻包含其中一部分關鍵詞就行
如果用match下指定了一個确切值,在遇到數字,日期,布爾值或者not_analyzed 的字元串時,它将為你搜尋你給定的值。
補充:個人感覺match查詢相當于模糊比對,隻包含其中一部分關鍵詞就行,這句話又誤,match應該也是精确查詢,與term的差別是 term不會有分析器分析的過程。如果想要模糊查詢的話,還是用wildcard加通配符。
格式
GET /library/books/_search
{
"query":{
"match":{
"key":"value"
}
}
}
執行個體1:過濾出preview字段中包含"elasticsearch"的索引,并且隻顯示preview和title字段
GET /library/books/_search
{
"fields":["preview","title"]
"query":{
"match":{
"preview":"elasticsearch"
}
}
}
如果你在一個全文字段上使用
match
查詢,在執行查詢前,它将用正确的分析器去分析查詢字元串:
{ "match": { "tweet": "About Search" }}
如果在一個精确值的字段上使用它,例如數字、日期、布爾或者一個
not_analyzed
字元串字段,那麼它将會精确比對給定的值:
{ "match": { "age": 26 }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "public": true }}
{ "match": { "tag": "full_text" }}
match_all查詢
查詢指定索引下的所有文檔
執行個體1:過濾出index為library,type為books的所有文檔
GET /library/books/_search
{
"query":{
"match_all":{}
}
}
執行個體2:通過match_all過濾出所有字段,然後通過partial在過濾出包含preview的字段和排除title,price的字段
GET /library/books/_search
{
"partial_fields":{
"partial":{
"include":["preview"], #包含preview字段的文檔
"exclude":["title,price"] #排除title,price字段
},
"query":{
"match_all":[]
}
}
}
match_phrase查詢
短語查詢,slop定義的是關鍵詞之間隔多少未知單詞
格式
GET /library/books/_search
{
"query":{
"match_phrase" :{
"query":"Elasticsearch,distributed",
"slop":2 #表示Elasticsearch和distributed之間隔多少單詞
}
}
}
multi_match查詢
可以指定多個字段
執行個體1:查詢title和preview這兩個字段都包含Elasticsearch關鍵詞的文檔
GET /library/books/_search
{
"query":{
"multi_match":{
"query":"Elasticsearch"
"fields":["title","preview"]
}
}
}
multi_match
查詢可以在多個字段上執行相同的
match
查詢:
{
"multi_match": {
"query": "full text search",
"fields": [ "title", "body" ]
}
}
range
查詢找出那些落在指定區間内的數字或者時間:
range
{
"range": {
"age": {
"gte": 20,
"lt": 30
}
}
}
被允許的操作符如下:
gt
大于
gte
大于等于
lt
小于
lte
小于等于
exists 查詢和 missing 查詢
exists
查詢和
missing
查詢被用于查找那些指定字段中有值 (
exists
) 或無值 (
missing
) 的文檔。這與SQL中的
IS_NULL
(
missing
) 和
NOT IS_NULL
(
exists
) 在本質上具有共性:
{
"exists": {
"field": "title"
}
}
filter過濾查詢
查詢同時,通過filter條件在不影響打分的情況下篩選出想要的資料
簡單的filter查詢
執行個體1:先查詢index為store,type為products的全部文檔;再過濾price等于20的
GET /store/products/_search
{
"query": {
"filtered":{
"query":{
"match_all": {} #先查詢index為store,type
},
"filter": {
"term" :{
"price":20 #這裡是條件,price等于20的
}
}
}
}
}
filter之bool過濾查詢
格式
{
"bool":{
"must" : [],
"should" : [],
"must_not" : [],
}
}
#must:條件必須滿足,相當于sql語句的and
#should:條件可以滿足也可以不滿足,相當于sql語句的or
#must_not:條件不需要滿足,相當于sql語句的not
執行個體1:查詢價格等于20或者productID等于SD1002136的商品,再排除價格等于30的
GET /store/products/_search
{
"query": {
"filtered":{
"filter":{
"bool":{
"should": [
{"term" : {"price" : 20}},
{"term" : {"productID" : "SD1002136"}}
],
"must_not": {
"term" :{"price":30}
}
}
}
}
}
}
filter之and,not,or查詢
沒有bool,也可以直接使用and,or,not
執行個體1:and用法,查詢價格是10元并且productID又是SD1002136的結果
GET /store/products/_search
{
"query":{
"filtered":{
"filter":{
"and":[
{
"term":{
"price":10
}
},
{
"term":{
"productID":"SD1002136"
}
}
]
},
"query":{
"match_all": {}
}
}
}
}
執行個體2:or用法,查詢價格是10元或者productID是SD4535233的商品
GET /store/products/_search
{
"query":{
"filtered":{
"filter":{
"or":[
{
"term":{
"price":10
}
},
{
"term":{
"productID":"SD4535233"
}
}
]
},
"query":{
"match_all":{}
}
}
}
}
執行個體3:not用法,查詢productID不是SD1002136的商品
GET /store/products/_search
{
"query":{
"filtered":{
"filter":{
"not":{
"term":{
"productID":"SD1002136"
}
}
},
"query":{
"match_all": {}
}
}
}
}
filter之range範圍查詢
格式
GET /store/products/_search
{
"query":{
"filtered":{
"filter":{
"range":{
"key":{
"條件" : value1
"條件": value2
}
}
}
}
}
}
條件
gt : 大于
lt : 小于
gte : 大于等于
lte :小于等于
執行個體1:查詢price大于等于20小于等于40的結果
GET /store/products/_search
{
"query":{
"filtered":{
"filter":{
"range":{
"price":{
"gte" : 20,
"lte" : 40
}
}
}
}
}
}
轉載于:https://www.cnblogs.com/zhaijunming5/p/6427100.html
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_most_important_queries.html#_exists_%E6%9F%A5%E8%AF%A2%E5%92%8C_missing_%E6%9F%A5%E8%AF%A2