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

1.简单查询

这种查询方式很简单,但比较局限。 查询last_name字段中含有smith一词的文档,可以这样写:

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

  1. {
  2. "query" : {
  3. "query_string" : {
  4. "query" : "last_name:smith"
  5. }
  6. }
  7. }

返回格式如下:

  1. {
  2. "took": 15,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 5,
  6. "successful": 5,
  7. "failed": 0
  8. },
  9. "hits": {
  10. "total": 2,
  11. "max_score": 0.30685282,
  12. "hits": [
  13. {
  14. "_index": "megacorp",
  15. "_type": "employee",
  16. "_id": "2",
  17. "_score": 0.30685282,
  18. "_source": {
  19. "first_name": "Jane",
  20. "last_name": "Smith",
  21. "age": 32,
  22. "about": "I like to collect rock albums",
  23. "interests": [
  24. "music"
  25. ]
  26. }
  27. },
  28. {
  29. "_index": "megacorp",
  30. "_type": "employee",
  31. "_id": "1",
  32. "_score": 0.30685282,
  33. "_source": {
  34. "first_name": "John",
  35. "last_name": "Smith",
  36. "age": 25,
  37. "about": "I love to go rock climbing",
  38. "interests": [
  39. "sports",
  40. "music"
  41. ]
  42. }
  43. }
  44. ]
  45. }
  46. }

pretty=true参数会让Elasticsearch以更容易阅读的方式返回响应。

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

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

  1. {
  2. "version" : true,//返回版本号
  3. "from" : 1,//从哪个文档开始(数组所以有0)
  4. "size" : 20,//返回多少个文档
  5. "query" : {
  6. "query_string" : {
  7. "query" : "last_name:smith"
  8. }
  9. }
  10. }

选择返回字段(fields)

只返回age,about和last_name字段

  1. {
  2. "fields":[ "age", "about","last_name" ],
  3. "query" : {
  4. "query_string" : {
  5. "query" : "last_name:Smith"
  6. }
  7. }
  8. }

返回格式如下:

  1. {
  2. "took": 3,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 5,
  6. "successful": 5,
  7. "failed": 0
  8. },
  9. "hits": {
  10. "total": 2,
  11. "max_score": 0.30685282,
  12. "hits": [
  13. {
  14. "_index": "megacorp",
  15. "_type": "employee",
  16. "_id": "2",
  17. "_score": 0.30685282,
  18. "fields": {
  19. "about": [
  20. "I like to collect rock albums"
  21. ],
  22. "last_name": [
  23. "Smith"
  24. ],
  25. "age": [
  26. 32
  27. ]
  28. }
  29. },
  30. {
  31. "_index": "megacorp",
  32. "_type": "employee",
  33. "_id": "1",
  34. "_score": 0.30685282,
  35. "fields": {
  36. "about": [
  37. "I love to go rock climbing"
  38. ],
  39. "last_name": [
  40. "Smith"
  41. ],
  42. "age": [
  43. 25
  44. ]
  45. }
  46. }
  47. ]
  48. }
  49. }
  • 如果没有定义fields数组,它将用默认值,如果有就返回_source字段;
  • 如果使用_source字段,并且请求一个没有存储的字段,那么这个字段将从_source字段中提取(然而,这需要额外的处理);
  • 如果想返回所有的存储字段,只需传入星号()作为字段名字。 *从性能的角度,返回_source字段比返回多个存储字段更好。

部分字段(include、exclude)

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

  1. {
  2. "partial_fields" : {
  3. "partial1" : {
  4. "include" : [ "titl*" ],
  5. "exclude" : [ "chara*" ]
  6. }
  7. },
  8. "query" : {
  9. "query_string" : { "query" : "title:crime" }
  10. }
  11. }

脚本字段(script_fields)

在JSON的查询对象中加上script_fields部分,添加上每个想返回的脚本值的名字。若要返回一个叫correctYear的值,它用year字段减去1800计算得来,运行以下查询:

  1. {
  2. "script_fields" : {
  3. "correctYear" : {
  4. "script" : "doc['year'].value - 1800"
  5. }
  6. },
  7. "query" : {
  8. "query_string" : { "query" : "title:crime" }
  9. }
  10. }

上面的示例中使用了doc符号,它让我们捕获了返回结果,从而让脚本执行速度更快,但也导致了更高的内存消耗,并且限制了只能用单个字段的单个值。如果关心内存的使用,或者使用的是更复杂的字段值,可以用_source字段。使用此字段的查询如下所示

  1. {
  2. "script_fields" : {
  3. "correctYear" : {
  4. "script" : "_source.year - 1800"
  5. }
  6. },
  7. "query" : {
  8. "query_string" : { "query" : "title:crime" }
  9. }
  10. }

返回格式如下:

  1. {
  2. "took" : 1,
  3. "timed_out" : false,
  4. "_shards" : {
  5. "total" : 5,
  6. "successful" : 5,
  7. "failed" : 0
  8. },
  9. "hits" : {
  10. "total" : 1,
  11. "max_score" : 0.15342641,
  12. "hits" : [ {
  13. "_index" : "library",
  14. "_type" : "book",
  15. "_id" : "4",
  16. "_score" : 0.15342641,
  17. "fields" : {
  18. "correctYear" : [ 86 ]
  19. }
  20. } ]
  21. }
  22. }

传参数到脚本字段中(script_fields)

一个脚本字段的特性:可传入额外的参数。可以使用一个变量名称,并把值传入params节中,而不是直接把1800写在等式中。这样做以后,查询将如下所示:

  1. {
  2. "script_fields" : {
  3. "correctYear" : {
  4. "script" : "_source.year - paramYear",
  5. "params" : {
  6. "paramYear" : 1800
  7. }
  8. }
  9. },
  10. "query" : {
  11. "query_string" : { "query" : "title:crime" }
  12. }
  13. }

基本查询

单词条查询:

最简单的词条查询如下所示:

  1. {
  2. "query" : {
  3. "term" : {
  4. "last_name" : "smith"
  5. }
  6. }
  7. }

多词条查询:

假设想得到所有在tags字段中含有novel或book的文档。运行以下查询来达到目的:

  1. {
  2. "query" : {
  3. "terms" : {
  4. "tags" : [ "novel", "book" ],
  5. "minimum_match" : 1
  6. }
  7. }
  8. }

上述查询返回在tags字段中包含一个或两个搜索词条的所有文档.minimum_match属性设置为1;这意味着至少有1个词条应该匹配。如果想要查询匹配所有词条的文档,可以把minimum_match属性设置为2。

match_all 查询

如果想得到索引中的所有文档,只需运行以下查询:

  1. {
  2. "query" : {
  3. "match_all" : {}
  4. }
  5. }

match 查询

  1. {
  2. "query" : {
  3. "match" : {
  4. "title" : "crime and punishment"
  5. }
  6. }
  7. }

上面的查询将匹配所有在title字段含有crime、and或punishment词条的文档。

match查询的几种类型

1 布尔值匹配查询(operator)

  1. {
  2. "query" : {
  3. "match" : {
  4. "title" : {
  5. "query" : "crime and punishment",
  6. "operator" : "and"
  7. }
  8. }
  9. }
  10. }

operator参数可接受or和and,用来决定查询中的所有条件的是or还是and。

2 match_phrase查询(slop)

这个可以查询类似 a+x+b,其中x是未知的。即知道了a和b,x未知的结果也可以查询出来。

  1. {
  2. "query" : {
  3. "match_phrase" : {
  4. "title" : {
  5. "query" : "crime punishment",
  6. "slop" : 1
  7. }
  8. }
  9. }
  10. }

注意,我们从查询中移除了and一词,但因为slop参数设置为1,它仍将匹配我们的文档。

slop:这是一个整数值,该值定义了文本查询中的词条和词条之间可以有多少个未知词条,以被视为跟一个短语匹配。此参数的默认值是0,这意味着,不允许有额外的词条,即上面的x可以是多个。

3 match_phrase_prefix查询

  1. {
  2. "query" : {
  3. "match_phrase_prefix" : {
  4. "title" : {
  5. "query" : "crime and punishm",
  6. "slop" : 1,
  7. "max_expansions" : 20
  8. }
  9. }
  10. }
  11. }

注意,我们没有提供完整的“crime and punishment”短语,而只是提供“crime and punishm”,该查询仍将匹配我们的文档。

multi_match 查询

multi_match查询和match查询一样,但是可以通过fields参数针对多个字段查询。当然,match查询中可以使用的所有参数同样 可以在multi_match查询中使用。所以,如果想修改match查询,让它针对title和otitle字段运行,那么运行以下查询:

  1. {
  2. "query" : {
  3. "multi_match" : {
  4. "query" : "crime punishment",
  5. "fields" : [ "title", "otitle" ]
  6. }
  7. }
  8. }

前缀查询

想找到所有title字段以cri开始的文档,可以运行以下查询:

  1. {
  2. "query" : {
  3. "prefix" : {
  4. "title" : "cri"
  5. }
  6. }
  7. }

通配符查询

这里?表示任意字符:

  1. {
  2. "query" : {
  3. "wildcard" : {
  4. "title" : "cr?me"
  5. }
  6. }
  7. }

范围查询

  • gte:范围查询将匹配字段值大于或等于此参数值的文档。
  • gt:范围查询将匹配字段值大于此参数值的文档。
  • lte:范围查询将匹配字段值小于或等于此参数值的文档。
  • lt:范围查询将匹配字段值小于此参数值的文档。

举例来说,要找到year字段从1700到1900的所有图书,可以运行以下查询:

  1. {
  2. "query" : {
  3. "range" : {
  4. "year" : {
  5. "gte" : 1700,
  6. "lte" : 1900
  7. }
  8. }
  9. }
  10. }

复合查询

布尔查询

  • should:被它封装的布尔查询可能被匹配,也可能不被匹配。被匹配的should节点数由minimum_should_match参数控制。
  • must:被它封装的布尔查询必须被匹配,文档才会返回。
  • must_not:被它封装的布尔查询必须不被匹配,文档才会返回。

假设我们想要找到所有这样的文档:在title字段中含有crime词条,并且year字段可以在也可以不在1900~2000的范围里,在otitle字段中不可以包含nothing词条。用布尔查询的话,类似于下面的代码:

  1. {
  2. "query" : {
  3. "bool" : {
  4. "must" : {
  5. "term" : {
  6. "title" : "crime"
  7. }
  8. },
  9. "should" : {
  10. "range" : {
  11. "year" : {
  12. "from" : 1900,
  13. "to" : 2000
  14. }
  15. }
  16. },
  17. "must_not" : {
  18. "term" : {
  19. "otitle" : "nothing"
  20. }
  21. }
  22. }
  23. }
  24. }

过滤器(不太理解过滤器的作用)

返回给定title的所有文档,但结果缩小到仅在1961年出版的书。使用filtered查询。如下:

  1. {
  2. "query": {
  3. "filtered" : {
  4. "query" : {
  5. "match" : { "title" : "Catch-22" }
  6. },
  7. "filter" : {
  8. "term" : { "year" : 1961 }
  9. }
  10. }
  11. }
  12. }

Demo

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

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

  1. //php代码
  2. $esjson = array();
  3. $esjson['query']['bool']['must'][] = array("term" => array("mid" => $mid));
  4. $esjson['query']['bool']['must'][] = array("term" => array("subscribe" => 1));
  5. $esjson['aggs'] = array("type_count" => array("value_count" => array("field" => "id")));
  1. {
  2. "query":{
  3. "bool":{
  4. "must":[
  5. {
  6. "term":{"mid":"55"}
  7. },{
  8. "term":{"subscribe":1}
  9. }]
  10. }
  11. },
  12. "aggs":{
  13. "type_count":{
  14. "value_count":{"field":"id"}
  15. }
  16. }
  17. }

2.查询wechat_customer 中mid等于$mid,$rule大于等于$start,且subscribe等于1的人数。(聚合默认返回的条数为10,如果加上size等于0的参数则返回所有)

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

esjson

  1. {
  2. "query":{
  3. "bool":{
  4. "must":[
  5. {
  6. "range":{
  7. "action_count":{"gte":"15"}
  8. }
  9. },
  10. {
  11. "term":{"mid":"55"}
  12. },
  13. {
  14. "term":{"subscribe":"1"}
  15. }
  16. ]
  17. }
  18. },
  19. "aggs":{
  20. "type_count":{
  21. "value_count":{"field":"id"}
  22. }
  23. }
  24. }

Elasticsearch查询的更多相关文章

  1. elasticsearch 查询(match和term)

    elasticsearch 查询(match和term) es中的查询请求有两种方式,一种是简易版的查询,另外一种是使用JSON完整的请求体,叫做结构化查询(DSL). 由于DSL查询更为直观也更为简 ...

  2. Func<T,T>应用之Elasticsearch查询语句构造器的开发

    前言 之前项目中做Elasticsearch相关开发的时候,虽然借助了第三方的组件PlainElastic.Net,但是由于当时不熟悉用法,而选择了自己拼接查询语句.例如: string queryG ...

  3. ElasticSearch查询 第五篇:布尔查询

    布尔查询是最常用的组合查询,不仅将多个查询条件组合在一起,并且将查询的结果和结果的评分组合在一起.当查询条件是多个表达式的组合时,布尔查询非常有用,实际上,布尔查询把多个子查询组合(combine)成 ...

  4. 利用kibana插件对Elasticsearch查询

    利用kibana插件对Elasticsearch查询 Elasticsearch是功能非常强大的搜索引擎,使用它的目的就是为了快速的查询到需要的数据. 查询分类: 基本查询:使用Elasticsear ...

  5. ElasticSearch查询 第四篇:匹配查询(Match)

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  6. elasticsearch查询语句总结

    query 和  filter 的区别请看:https://www.cnblogs.com/bainianminguo/articles/10396956.html Filter DSL term 过 ...

  7. (转载)elasticsearch 查询(match和term)

    原文地址:https://www.cnblogs.com/yjf512/p/4897294.html elasticsearch 查询(match和term) es中的查询请求有两种方式,一种是简易版 ...

  8. ElasticSearch查询 第三篇:词条查询

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  9. ElasticSearch查询 第二篇:文档更新

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  10. ElasticSearch查询 第一篇:搜索API

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

随机推荐

  1. English Literature

    The website links of English Literature,which I wanno recommend to U is based on following. 数据结构 - 知 ...

  2. 20145224&20145238 《信息安全系统设计基础》 第一次实验

    20145224&20145238 <信息安全系统设计基础>第一次实验 课程:信息安全系统设计基础 班级:1452 姓名:陈颢文 荆玉茗 学号:20145224 20145238 ...

  3. 如何根据不同的浏览器写不同的css样式达到兼容

    做前端静态页面的时候总是发现,ie的兼容性很差,总会出点问题.然后就去改代码 ,改完以后 又发现 火狐 谷歌又挂了,这可咋整.     后来发现做个判断吧 哪里有问题哪里就做个判断呗 ,咋判断呢,这么 ...

  4. Educational Codeforces Round 14 D. Swaps in Permutation

    题目链接 分析:一些边把各个节点连接成了一颗颗树.因为每棵树上的边可以走任意次,所以不难想出要字典序最大,就是每棵树中数字大的放在树中节点编号比较小的位置. 我用了极为暴力的方法,先dfs每棵树,再用 ...

  5. sC#进阶系列——WebApi 接口参数不再困惑:传参详解

    原文:http://www.cnblogs.com/landeanfen/p/5337072.html 一.get请求 对于取数据,我们使用最多的应该就是get请求了吧.下面通过几个示例看看我们的ge ...

  6. Jquery之ShowLoading遮罩组件

    From:http://www.cnblogs.com/eczhou/archive/2012/12/18/2822788.html 一.遮罩用途及效果 ShowLoading这个jQuery插件设计 ...

  7. 关闭缓存和mmu(转)

    当设置完时钟分频以后,uboot就会执行cpu_init_crit汇编函数,这个函数的主要作用就是关闭缓存和mmu,然后调用lowlevel_init函数进行系统总线的初始化. 为什么启动的时候,需要 ...

  8. c#中各类日期的计算方法,收藏

    DateTime startWeek = dt.AddDays(1 - Convert.ToInt32(dt.DayOfWeek.ToString("d")));  //本周周一D ...

  9. QT_BEGIN_NAMESPACE QT_END_NAMESPACE

    QT_BEGIN_NAMESPACEQT_END_NAMESPACE 在源代码中是这样定义的: 1 2 # define QT_BEGIN_NAMESPACE namespace QT_NAMESPA ...

  10. 【LeetCode OJ】Flatten Binary Tree to Linked List

    Problem Link: http://oj.leetcode.com/problems/flatten-binary-tree-to-linked-list/ The problem is ask ...