ElasticSearch查詢怎么使用

這篇文章主要講解了“ElasticSearch查詢怎么使用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“ElasticSearch查詢怎么使用”吧!

新野ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18982081108(備注:SSL證書合作)期待與您的合作!

搜索api

有兩種方法執(zhí)行搜索:第一種是通過REST request Uri 發(fā)送搜索參數(shù),第二種是通過REST request body。第二種方法允許你用json格式定義更豐富的查詢參數(shù)。我們將會用第一種方法做一個(gè)例子,但之后都會專一地使用第二種方法做實(shí)驗(yàn)。

_search 返回 bank索引的所有文檔

GET /bank/_search?q=*&sort=account_number:asc

q=* :查詢所有

返回結(jié)果如下:

{
  "took" : 82,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : null,
    "hits" : [ {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "0",
      "sort": [0],
      "_score" : null,
      "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
    }, {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "1",
      "sort": [1],
      "_score" : null,
      "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
    }, ...
    ]
  }
}
  • took-elasticsearch執(zhí)行搜索花費(fèi)的毫秒數(shù)

  • timed_out-告訴我們這次搜索是否超時(shí)

  • _shards- 告訴我們搜索了多少個(gè)分片,以及搜索成功和失敗的分片數(shù)

  • hits-搜索返回的文檔結(jié)果

  • hits.total 一共命中了多少結(jié)果

  • sort-搜索排序規(guī)則,如果沒有該字段,則按相關(guān)度排序

  • _score和max_score 暫時(shí)先忽略這個(gè)參數(shù)(文檔得分,反映相關(guān)度)

下面用request body方法執(zhí)行和上面一樣的搜索操作:

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}

query 字段說明查詢內(nèi)容

match_all是執(zhí)行查詢操作的匹配類型 , match_all是匹配所有文檔的意思。

不同點(diǎn)是我們用json格式的請求體代替了_search api uri中的q=*參數(shù)。

必須要知道的是:當(dāng)我們接收到返回結(jié)果的時(shí)候,elasticsearch已經(jīng)完全處理了這個(gè)請求,不會維護(hù)任何的服務(wù)器資源或游標(biāo)到你的返回結(jié)果中。這與類似sql這樣的平臺形成鮮明的對比,sql允許你先取前面的一部分?jǐn)?shù)據(jù),然后連續(xù)不斷的通過服務(wù)器端的游標(biāo)再去取剩下的數(shù)據(jù)。

基本語法

除了query參數(shù),我們也可以傳遞其他參數(shù)去影響查詢結(jié)果。在上一章節(jié)的例子我們傳遞了一個(gè)sort參數(shù),這里我們傳遞一個(gè)size

GET /bank/_search
{
  "query": { "match_all": {} },
  "size": 1
}

注意,如果size沒有指定,默認(rèn)值是10.

下面這個(gè)例子匹配所有文檔,并返回第11-20的文檔:

GET /bank/_search
{
  "query": { "match_all": {} },
  "from": 10,
  "size": 10
}

from參數(shù)指定從第幾個(gè)文檔開始返回,size參數(shù)指定一共返回多少個(gè)文檔。這個(gè)特性是對分頁功能是十分重要的。如果from沒有指定,默認(rèn)值是0。

下面的例子按賬戶余額倒序查詢前10個(gè)結(jié)果(默認(rèn)size大?。?/p>

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": { "balance": { "order": "desc" } }
}

match查詢

現(xiàn)在我已經(jīng)看見過一些基礎(chǔ)的查詢參數(shù),讓我們挖掘更多關(guān)于query DSL 的信息。首先看看返回文檔的字段。默認(rèn)所有的字段都會被返回。文檔原始內(nèi)容被稱為源(對應(yīng)hits中的_source 鍵)。如果我們不想返回文檔的所有字段,也可以僅僅要求接口返回部分字段。

下面的例子展示如何返回 account_number 和balance(在_source里面)這個(gè)兩個(gè)字段:

GET /bank/_search
{
  "query": { "match_all": {} },
  "_source": ["account_number", "balance"]
}

注意上述操作只是減少了返回的字段,但是_source字段還是存在的,只是僅返回account_numberbalance字段

如果你曾經(jīng)學(xué)過sql,上述概念就和sql select filed list from 差不多。

現(xiàn)在,讓我們繼續(xù)學(xué)習(xí)查詢語法。之前,我們已經(jīng)看到過match_all查詢類型使用來匹配所有文檔的?,F(xiàn)在,我們介紹一種新的查詢類型match,他是基于字段搜索的(即,通過匹配一個(gè)特定的字段或一組字段執(zhí)行搜索)

下面的例子返回賬號number是20的文檔:

GET /bank/_search
{
  "query": { "match": { "account_number": 20 } }
}

下面的例子返回所有地址字段包含mill的賬戶文檔

GET /bank/_search
{
  "query": { "match": { "address": "mill" } }
}

下面的例子返回地址字段包含“mill”或者“l(fā)ane”的賬戶

GET /bank/_search
{
  "query": { "match": { "address": "mill lane" } }
}

match_phrase查詢(短語匹配)

下面的例子是match的變種(match_phrase),它返回所有地址字段包含詞組“mill lane”的賬戶

GET /bank/_search
{
  "query": { "match_phrase": { "address": "mill lane" } }
}

bool查詢

現(xiàn)在,讓我介紹一下布爾查詢。bool查詢允許我們把多個(gè)match查詢合并到一個(gè)查詢中。

下面的例子合并了兩個(gè)match查詢并返回所有地址字段同時(shí)包含“mill”和“l(fā)ane”的賬戶

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

上述例子的bool must子句指定:當(dāng)所有的查詢都返回true的時(shí)候,才認(rèn)為匹配文檔。

與此相反,下面這個(gè)這個(gè)例子合并兩個(gè)match查詢,并返回所有地址地段包含“mill”或“l(fā)ane”的賬戶

GET /bank/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

上述例子,bool should 子句只要文檔滿足其中一個(gè)查詢,就認(rèn)為匹配。

下面的例子合并了兩個(gè)match查詢,并返回所有地址字段既不包含“mill”也不包含“l(fā)ane”的賬戶:

GET /bank/_search
{
  "query": {
    "bool": {
      "must_not": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

上面的例子中,bool must_not子句指定當(dāng)所有查詢都不滿足的時(shí)候,就認(rèn)為匹配文檔。

我們也可以把must,shouldmust_not同時(shí)組合到bool子句。此外,我們也可以組合bool 到任何一個(gè)bool子句中,實(shí)現(xiàn)復(fù)雜的多層bool子句嵌套邏輯。

下面的例子返回所有年齡是40歲但不是住在ID州的賬戶:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}

filter查詢

在之前的章節(jié),我們跳過了一個(gè)小細(xì)節(jié):文檔得分(搜索結(jié)果的_score字段).文檔得分是一個(gè)數(shù)字值,它代表關(guān)鍵字和文檔內(nèi)容的相關(guān)度估值。 文檔得分越高說明相關(guān)度越高,文檔得分越少,說明相關(guān)度越少。

但查詢不一定都需要產(chǎn)生文檔得分,特別在過濾文檔集合的時(shí)候。為了避免不必要的文檔得分計(jì)算,Elasticsearch會檢查這種情況并自動的優(yōu)化這種查詢。

在前面章節(jié)介紹的bool查詢也支持filter子句,它允許你使用一個(gè)查詢語句去過濾其它子句的匹配結(jié)果,同時(shí)不會改變文檔的得分。我們介紹一下range查詢,并把它作為例子,它允許我們通過一個(gè)范圍值去過濾文檔。通常用于數(shù)字或日期過濾。

這個(gè)例子使用bool查詢返回所有賬戶余額在20000-30000之間的文檔。換句話說,我們需要查找余額大于20000小于30000的賬戶:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

仔細(xì)分析上面的例子,bool查詢包含了一個(gè)match_all查詢(查詢部分)和一個(gè)range查詢(過濾部分)。我們也可以用任何其它的查詢語句代替查詢和過濾部分的語句。對于上面的例子,因?yàn)樗形臋n都是指定范圍之內(nèi)的,他們從某種意義上來說是等價(jià)的(equally),即他們的相關(guān)度都是一樣的(filter子句查詢,不會改變得分)。

除了 match_all,match,bool,range查詢,還有很多種類的查詢,但我們不在這里一一介紹。從現(xiàn)在開始,我們對查詢已經(jīng)有一個(gè)基礎(chǔ)的了解,把學(xué)到的知識應(yīng)用到其他查詢類型應(yīng)該也沒什么難度。

term查詢

GET /bank/_search
{
  "query": {
    "term": {
      "address": "789 Madison"
    }
  }
}

match精確匹配

GET /bank/_search
{
  "query": {
    "match": {
      "address.keyword": "789 Madison"
    }
  }
}

term,match,match_phase,query_string,keyword精確匹配的區(qū)別

1. match

match:模糊匹配,需要指定字段名,但是輸入會進(jìn)行分詞,比如"hello world"會進(jìn)行拆分為hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的結(jié)果都會被查詢出來,也就是說match是一個(gè)部分匹配的模糊查詢。查詢條件相對來說比較寬松。

2. term

term: 這種查詢和match在有些時(shí)候是等價(jià)的,比如我們查詢單個(gè)的詞hello,那么會和match查詢結(jié)果一樣,但是如果查詢"hello world",結(jié)果就相差很大,因?yàn)檫@個(gè)輸入不會進(jìn)行分詞,就是說查詢的時(shí)候,是查詢字段分詞結(jié)果中是否有"hello world"的字樣,而不是查詢字段中包含"hello world"的字樣,elasticsearch會對字段內(nèi)容進(jìn)行分詞,"hello world"會被分成hello和world,不存在"hello world",因此這里的查詢結(jié)果會為空。這也是term查詢和match的區(qū)別。

3. match_phase

match_phase:會對輸入做分詞,但是需要結(jié)果中也包含所有的分詞,而且順序要求一樣。以"hello world"為例,要求結(jié)果中必須包含hello和world,而且還要求他們是連著的,順序也是固定的,hello that word不滿足,world hello也不滿足條件。

4. query_string

query_string:和match類似,但是match需要指定字段名,query_string是在所有字段中搜索,范圍更廣泛。

5. keyword精確匹配

不同于term,keyword精確匹配要求查詢的字段必須等于

一般我們?nèi)臋z索字段用match,其他非text字段匹配用term

執(zhí)行聚合(Executing Aggregations)

聚合功能能夠分組并統(tǒng)計(jì)你的數(shù)據(jù)。最簡單的說法就是等價(jià)于sql group by 語句和sql的聚合函數(shù)。使用elasticsearch,你可以同時(shí)在一個(gè)請求中返回需要查詢的數(shù)據(jù)以及這些數(shù)據(jù)的多種聚合運(yùn)算結(jié)果。在單個(gè)請求中就可以同時(shí)查詢數(shù)據(jù)和進(jìn)行多次聚合運(yùn)算是非常有意義的,他可以降低網(wǎng)絡(luò)請求的次數(shù)。

下面的例子把state字段的內(nèi)容分組,并按照每一組的文檔數(shù)量倒序排序,返回?cái)?shù)量最多的前10(默認(rèn)值)組數(shù)據(jù):

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}

上面的聚合運(yùn)算等價(jià)于執(zhí)行下面的sql:

SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC

返回結(jié)果(僅展示一部分):

{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets" : [ {
        "key" : "ID",
        "doc_count" : 27
      }, {
        "key" : "TX",
        "doc_count" : 27
      }, {
        "key" : "AL",
        "doc_count" : 25
      }, {
        "key" : "MD",
        "doc_count" : 25
      }, {
        "key" : "TN",
        "doc_count" : 23
      }, {
        "key" : "MA",
        "doc_count" : 21
      }, {
        "key" : "NC",
        "doc_count" : 21
      }, {
        "key" : "ND",
        "doc_count" : 21
      }, {
        "key" : "ME",
        "doc_count" : 20
      }, {
        "key" : "MO",
        "doc_count" : 20
      } ]
    }
  }
}

我們可以看到,ID州有27個(gè)賬戶,隨后的TX州有27個(gè)賬戶,AL州有25個(gè)賬戶。

注意我們設(shè)置size=0是因?yàn)槲也恍枰樵兾臋n,只需要查詢聚合結(jié)果。

基于上述例子,下面的例子除了分組還會計(jì)算每個(gè)州的賬戶的平均余額:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

注意我們是如何把a(bǔ)verage_balance聚合嵌入到group_by_state聚合中。這種模式適合于所有的聚合。你可以按你的需求重復(fù)嵌套聚合子句,匯總你的數(shù)據(jù)。

基于上面的例子,我們加入了按每個(gè)州的賬戶平均余額倒序排序的限制(說明了上一層聚合可以使用下一層聚合的運(yùn)算結(jié)果):

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

下面例子講述了我們?nèi)绾伟茨挲g組分組(20-29,30-39,40-49),然后按性別分組,最后獲取每個(gè)組中每個(gè)性別的賬戶平均余額。(例如:年齡段在20-29的女性用戶的賬戶平均余額)

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 20,
            "to": 30
          },
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "group_by_gender": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "average_balance": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}

最后一個(gè)例子,查出所有年齡分布,并且這些年齡段中性別M的平均薪資和F的平均薪資以及這個(gè)年齡段的總體平均薪資

GET /bank/_search
{
  "size": 0, 
  "aggs":{
    "aggAgg": {
      "terms": {
        "field": "age"
      },
      "aggs": {
        "ageBalanceAvg":{
          "avg": {
            "field": "balance"
          }
        },
        "genderAgg":{
          "terms":{
            "field": "gender.keyword"
          },
          "aggs": {
            "avgAvg":{
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}

感謝各位的閱讀,以上就是“ElasticSearch查詢怎么使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對ElasticSearch查詢怎么使用這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

分享題目:ElasticSearch查詢怎么使用
鏈接地址:http://bm7419.com/article40/ijpheo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、網(wǎng)站設(shè)計(jì)網(wǎng)站策劃、ChatGPT、動態(tài)網(wǎng)站電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站