Elasticsearch查詢類型


Elasticsearch支持兩種類型的查詢:基本查詢和復合查詢。 基本查詢,如詞條查詢用於查詢實際數據。 復合查詢,如布爾查詢,可以合並多個查詢, 然而,這不是全部。除了這兩種類型的查詢,你還可以用過濾查詢,根據一定的條件縮小查詢結果。不像其他查詢,篩選查詢不會影響得分,而且通常非常高效。 更加復雜的情況,查詢可以包含其他查詢。此外,一些查詢可以包含過濾器,而其他查詢可同時包含查詢和過濾器。這並不是全部,但暫時先解釋這些工作。

1.簡單查詢

這種查詢方式很簡單,但比較局限。 查詢last_name字段中含有smith一詞的文檔,可以這樣寫:

http://127.0.0.1:9200/megacorp/employee/_search

{
    "query" : { "query_string" : { "query" : "last_name:smith" } } } 

返回格式如下:

{
  "took": 15, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 2, "max_score": 0.30685282, "hits": [ { "_index": "megacorp", "_type": "employee", "_id": "2", "_score": 0.30685282, "_source": { "first_name": "Jane", "last_name": "Smith", "age": 32, "about": "I like to collect rock albums", "interests": [ "music" ] } }, { "_index": "megacorp", "_type": "employee", "_id": "1", "_score": 0.30685282, "_source": { "first_name": "John", "last_name": "Smith", "age": 25, "about": "I love to go rock climbing", "interests": [ "sports", "music" ] } } ] } } 

pretty=true參數會讓Elasticsearch以更容易閱讀的方式返回響應。

2.分頁和結果集大小(form、size)

Elasticsearch能控制想要的最多結果數以及想從哪個結果開始。下面是可以在請求體中添加的兩個額外參數。 from:該屬性指定我們希望在結果中返回的起始文檔。它的默認值是0,表示想要得到從第一個文檔開始的結果。 size:該屬性指定了一次查詢中返回的最大文檔數,默認值為10。如果只對切面結果感興趣,並不關心文檔本身,可以把這個參數設置成0。 如果想讓查詢從第2個文檔開始返回20個文檔,可以發送如下查詢:

{
    "version" : true,//返回版本號 "from" : 1,//從哪個文檔開始(數組所以有0) "size" : 20,//返回多少個文檔 "query" : { "query_string" : { "query" : "last_name:smith" } } } 

選擇返回字段(fields)

只返回age,about和last_name字段

{
    "fields":[ "age", "about","last_name" ], "query" : { "query_string" : { "query" : "last_name:Smith" } } } 

返回格式如下:

{
  "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "failed": 0 }, "hits": { "total": 2, "max_score": 0.30685282, "hits": [ { "_index": "megacorp", "_type": "employee", "_id": "2", "_score": 0.30685282, "fields": { "about": [ "I like to collect rock albums" ], "last_name": [ "Smith" ], "age": [ 32 ] } }, { "_index": "megacorp", "_type": "employee", "_id": "1", "_score": 0.30685282, "fields": { "about": [ "I love to go rock climbing" ], "last_name": [ "Smith" ], "age": [ 25 ] } } ] } } 
  • 如果沒有定義fields數組,它將用默認值,如果有就返回_source字段;
  • 如果使用_source字段,並且請求一個沒有存儲的字段,那么這個字段將從_source字段中提取(然而,這需要額外的處理);
  • 如果想返回所有的存儲字段,只需傳入星號()作為字段名字。 *從性能的角度,返回_source字段比返回多個存儲字段更好。

部分字段(include、exclude)

Elasticsearch公開了部分字段對象的include和exclude屬性,所以可以基於這些屬性來包含或排除字段。例如,為了在查詢中包括以titl開頭且排除以chara開頭的字段,發出以下查詢:

{
    "partial_fields" : { "partial1" : { "include" : [ "titl*" ], "exclude" : [ "chara*" ] } }, "query" : { "query_string" : { "query" : "title:crime" } } } 

腳本字段(script_fields)

在JSON的查詢對象中加上script_fields部分,添加上每個想返回的腳本值的名字。若要返回一個叫correctYear的值,它用year字段減去1800計算得來,運行以下查詢:

{
    "script_fields" : { "correctYear" : { "script" : "doc['year'].value - 1800" } }, "query" : { "query_string" : { "query" : "title:crime" } } } 

上面的示例中使用了doc符號,它讓我們捕獲了返回結果,從而讓腳本執行速度更快,但也導致了更高的內存消耗,並且限制了只能用單個字段的單個值。如果關心內存的使用,或者使用的是更復雜的字段值,可以用_source字段。使用此字段的查詢如下所示

{
    "script_fields" : { "correctYear" : { "script" : "_source.year - 1800" } }, "query" : { "query_string" : { "query" : "title:crime" } } } 

返回格式如下:

{
    "took" : 1, "timed_out" : false, "_shards" : { "total" : 5, "successful" : 5, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.15342641, "hits" : [ { "_index" : "library", "_type" : "book", "_id" : "4", "_score" : 0.15342641, "fields" : { "correctYear" : [ 86 ] } } ] } } 

傳參數到腳本字段中(script_fields)

一個腳本字段的特性:可傳入額外的參數。可以使用一個變量名稱,並把值傳入params節中,而不是直接把1800寫在等式中。這樣做以后,查詢將如下所示:

{
    "script_fields" : { "correctYear" : { "script" : "_source.year - paramYear", "params" : { "paramYear" : 1800 } } }, "query" : { "query_string" : { "query" : "title:crime" } } } 

基本查詢

單詞條查詢:

最簡單的詞條查詢如下所示:

{
    "query" : { "term" : { "last_name" : "smith" } } } 

多詞條查詢:

假設想得到所有在tags字段中含有novel或book的文檔。運行以下查詢來達到目的:

{
    "query" : { "terms" : { "tags" : [ "novel", "book" ], "minimum_match" : 1 } } } 

上述查詢返回在tags字段中包含一個或兩個搜索詞條的所有文檔.minimum_match屬性設置為1;這意味着至少有1個詞條應該匹配。如果想要查詢匹配所有詞條的文檔,可以把minimum_match屬性設置為2。

match_all 查詢

如果想得到索引中的所有文檔,只需運行以下查詢:

{
    "query" : { "match_all" : {} } } 

match 查詢

{
    "query" : { "match" : { "title" : "crime and punishment" } } } 

上面的查詢將匹配所有在title字段含有crime、and或punishment詞條的文檔。

match查詢的幾種類型

1 布爾值匹配查詢(operator)

{
    "query" : { "match" : { "title" : { "query" : "crime and punishment", "operator" : "and" } } } } 

operator參數可接受or和and,用來決定查詢中的所有條件的是or還是and。

2 match_phrase查詢(slop)

這個可以查詢類似 a+x+b,其中x是未知的。即知道了a和b,x未知的結果也可以查詢出來。

{
    "query" : { "match_phrase" : { "title" : { "query" : "crime punishment", "slop" : 1 } } } } 

注意,我們從查詢中移除了and一詞,但因為slop參數設置為1,它仍將匹配我們的文檔。

slop:這是一個整數值,該值定義了文本查詢中的詞條和詞條之間可以有多少個未知詞條,以被視為跟一個短語匹配。此參數的默認值是0,這意味着,不允許有額外的詞條,即上面的x可以是多個。

3 match_phrase_prefix查詢

{
    "query" : { "match_phrase_prefix" : { "title" : { "query" : "crime and punishm", "slop" : 1, "max_expansions" : 20 } } } } 

注意,我們沒有提供完整的“crime and punishment”短語,而只是提供“crime and punishm”,該查詢仍將匹配我們的文檔。

multi_match 查詢

multi_match查詢和match查詢一樣,但是可以通過fields參數針對多個字段查詢。當然,match查詢中可以使用的所有參數同樣 可以在multi_match查詢中使用。所以,如果想修改match查詢,讓它針對title和otitle字段運行,那么運行以下查詢:

{
    "query" : { "multi_match" : { "query" : "crime punishment", "fields" : [ "title", "otitle" ] } } } 

前綴查詢

想找到所有title字段以cri開始的文檔,可以運行以下查詢:

{
    "query" : { "prefix" : { "title" : "cri" } } } 

通配符查詢

這里?表示任意字符:

{
    "query" : { "wildcard" : { "title" : "cr?me" } } } 

范圍查詢

  • gte:范圍查詢將匹配字段值大於或等於此參數值的文檔。
  • gt:范圍查詢將匹配字段值大於此參數值的文檔。
  • lte:范圍查詢將匹配字段值小於或等於此參數值的文檔。
  • lt:范圍查詢將匹配字段值小於此參數值的文檔。

舉例來說,要找到year字段從1700到1900的所有圖書,可以運行以下查詢:

{
    "query" : { "range" : { "year" : { "gte" : 1700, "lte" : 1900 } } } } 

復合查詢

布爾查詢

  • should:被它封裝的布爾查詢可能被匹配,也可能不被匹配。被匹配的should節點數由minimum_should_match參數控制。
  • must:被它封裝的布爾查詢必須被匹配,文檔才會返回。
  • must_not:被它封裝的布爾查詢必須不被匹配,文檔才會返回。

假設我們想要找到所有這樣的文檔:在title字段中含有crime詞條,並且year字段可以在也可以不在1900~2000的范圍里,在otitle字段中不可以包含nothing詞條。用布爾查詢的話,類似於下面的代碼:

{
    "query" : { "bool" : { "must" : { "term" : { "title" : "crime" } }, "should" : { "range" : { "year" : { "from" : 1900, "to" : 2000 } } }, "must_not" : { "term" : { "otitle" : "nothing" } } } } } 

過濾器(不太理解過濾器的作用)

返回給定title的所有文檔,但結果縮小到僅在1961年出版的書。使用filtered查詢。如下:

{
    "query": { "filtered" : { "query" : { "match" : { "title" : "Catch-22" } }, "filter" : { "term" : { "year" : 1961 } } } } } 

Demo

1.查詢wechat_customer表中mid等於$mid,且subscribe=1的人。

http://localhost:9200/wechat_v6_count/wechat_customer/_search?search_type=count

//php代碼 $esjson = array(); $esjson['query']['bool']['must'][] = array("term" => array("mid" => $mid)); $esjson['query']['bool']['must'][] = array("term" => array("subscribe" => 1)); $esjson['aggs'] = array("type_count" => array("value_count" => array("field" => "id"))); 
{
    "query":{ "bool":{ "must":[ { "term":{"mid":"55"} },{ "term":{"subscribe":1} }] } }, "aggs":{ "type_count":{ "value_count":{"field":"id"} } } } 

2.查詢wechat_customer 中mid等於$mid,$rule大於等於$start,且subscribe等於1的人數。(聚合默認返回的條數為10,如果加上size等於0的參數則返回所有)

$esjson['query']['bool']['must'][] = array("range" => array($rule => array("gte"=>$start))); $esjson['query']['bool']['must'][] = array("term" => array("mid" => $mid)); $esjson['query']['bool']['must'][] = array("term" => array("subscribe" => 1)); $esjson['aggs'] = array("type_count" => array("value_count" => array("field" => "id"))); $esjson = json_encode($esjson); $esresult = ElasticsearchClient::searchForCount($esjson); $result = $esresult['aggregations']['type_count']['value']; //原來的sql //$sql = "SELECT count(*) as 'cnt' from wechat_customer where mid =:mid AND " . $rule . ">=:start AND subscribe=1;"; //$params = array(':mid' => $mid, ':start' => $start); 

esjson

{
    "query":{ "bool":{ "must":[ { "range":{ "action_count":{"gte":"15"} } }, { "term":{"mid":"55"} }, { "term":{"subscribe":"1"} } ] } }, "aggs":{ "type_count":{ "value_count":{"field":"id"} } } } 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM