Elasticsearch支持兩種類型的查詢:基本查詢和複合查詢。 基本查詢,如詞條查詢用於查詢實際數據。 複合查詢,如布爾查詢,能夠合併多個查詢, 然而,這不是所有。除了這兩種類型的查詢,你還能夠用過濾查詢,根據必定的條件縮小查詢結果。不像其餘查詢,篩選查詢不會影響得分,並且一般很是高效。 更加複雜的狀況,查詢能夠包含其餘查詢。此外,一些查詢能夠包含過濾器,而其餘查詢可同時包含查詢和過濾器。這並非所有,但暫時先解釋這些工做。php
這種查詢方式很簡單,但比較侷限。 查詢last_name字段中含有smith一詞的文檔,能夠這樣寫:sql
http://127.0.0.1:9200/megacorp/employee/_searchjson
{
"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以更容易閱讀的方式返回響應。性能
Elasticsearch能控制想要的最多結果數以及想從哪一個結果開始。下面是能夠在請求體中添加的兩個額外參數。 from:該屬性指定咱們但願在結果中返回的起始文檔。它的默認值是0,表示想要獲得從第一個文檔開始的結果。 size:該屬性指定了一次查詢中返回的最大文檔數,默認值爲10。若是隻對切面結果感興趣,並不關心文檔自己,能夠把這個參數設置成0。 若是想讓查詢從第2個文檔開始返回20個文檔,能夠發送以下查詢:spa
{
"version" : true,//返回版本號 "from" : 1,//從哪一個文檔開始(數組因此有0) "size" : 20,//返回多少個文檔 "query" : { "query_string" : { "query" : "last_name:smith" } } }
只返回age,about和last_name字段rest
{
"fields":[ "age", "about","last_name" ], "query" : { "query_string" : { "query" : "last_name:Smith" } } }
返回格式以下:code
{
"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 ] } } ] } }
Elasticsearch公開了部分字段對象的include和exclude屬性,因此能夠基於這些屬性來包含或排除字段。例如,爲了在查詢中包括以titl開頭且排除以chara開頭的字段,發出如下查詢:orm
{
"partial_fields" : { "partial1" : { "include" : [ "titl*" ], "exclude" : [ "chara*" ] } }, "query" : { "query_string" : { "query" : "title:crime" } } }
在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查詢和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" } } }
舉例來講,要找到year字段從1700到1900的全部圖書,能夠運行如下查詢:
{
"query" : { "range" : { "year" : { "gte" : 1700, "lte" : 1900 } } } }
布爾查詢
假設咱們想要找到全部這樣的文檔:在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 } } } } }
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"} } } }