Elasticsearch查询类型

Elasticsearch支持两种类型的查询:基本查询和复合查询。 基本查询,如词条查询用于查询实际数据。 复合查询,如布尔查询,能够合并多个查询, 然而,这不是所有。除了这两种类型的查询,你还能够用过滤查询,根据必定的条件缩小查询结果。不像其余查询,筛选查询不会影响得分,并且一般很是高效。 更加复杂的状况,查询能够包含其余查询。此外,一些查询能够包含过滤器,而其余查询可同时包含查询和过滤器。这并非所有,但暂时先解释这些工做。php

1.简单查询

这种查询方式很简单,但比较局限。 查询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以更容易阅读的方式返回响应。性能

2.分页和结果集大小(form、size)

Elasticsearch能控制想要的最多结果数以及想从哪一个结果开始。下面是能够在请求体中添加的两个额外参数。 from:该属性指定咱们但愿在结果中返回的起始文档。它的默认值是0,表示想要获得从第一个文档开始的结果。 size:该属性指定了一次查询中返回的最大文档数,默认值为10。若是只对切面结果感兴趣,并不关心文档自己,能够把这个参数设置成0。 若是想让查询从第2个文档开始返回20个文档,能够发送以下查询:spa

{
    "version" : true,//返回版本号 "from" : 1,//从哪一个文档开始(数组因此有0) "size" : 20,//返回多少个文档 "query" : { "query_string" : { "query" : "last_name:smith" } } } 

选择返回字段(fields)

只返回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 ] } } ] } } 
  • 若是没有定义fields数组,它将用默认值,若是有就返回_source字段;
  • 若是使用_source字段,而且请求一个没有存储的字段,那么这个字段将从_source字段中提取(然而,这须要额外的处理);
  • 若是想返回全部的存储字段,只需传入星号()做为字段名字。 *从性能的角度,返回_source字段比返回多个存储字段更好。

部分字段(include、exclude)

Elasticsearch公开了部分字段对象的include和exclude属性,因此能够基于这些属性来包含或排除字段。例如,为了在查询中包括以titl开头且排除以chara开头的字段,发出如下查询:orm

{
    "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"} } } } 
相关文章
相关标签/搜索