地理坐标点数据类型

  • 地理坐标点

地理坐标点是指地球表面可以用经纬度描述的一个点。 地理坐标点可以用来计算两个坐标间的距离,还可以判断一个坐标是否在一个区域中。地理坐标点需要显式声明对应字段类型为 geo_point
image.png

  • 经纬度坐标格式

如上例, location 字段被声明为 geo_point 后,我们就可以索引包含了经纬度信息的文档了。 经纬度信息的形式可以是字符串、数组或者对象
image.png
image.png
注意
字符串形式以半角逗号分割,如 “lat,lon”
对象形式显式命名为 lat 和 lon
数组形式表示为 [lon,lat]

  • 通过地理坐标点过滤

有四种地理坐标点相关的过滤器 可以用来选中或者排除文档
image.png

  • geo_bounding_box查询

这是目前为止最有效的地理坐标过滤器了,因为它计算起来非常简单。 你指定一个矩形的顶部 ,底部 , 左边界和右边界,然后过滤器只需判断坐标的经度是否在左右边界之间,纬度是否在上下边界之间
然后可以使用 geo_bounding_box 过滤器执行以下查询
image.png
location这些坐标也可以用 bottom_left 和 top_right 来表示

  • geo_distance

过滤仅包含与地理位置相距特定距离内的匹配的文档。假设以下映射和索引文档然后可以使用 geo_distance 过滤器执行以下查询
image.png

动态映射

Elasticsearch在遇到文档中以前未遇到的字段,可以使用dynamic mapping(动态映射机制) 来确定字段的数据类型并自动把新的字段添加到类型映射。
Elastic的动态映射机制可以进行开关控制,通过设置mappings的dynamic属性,dynamic有如下设置项

  • true:遇到陌生字段就执行dynamic mapping处理机制
  • false:遇到陌生字段就忽略
  • strict:遇到陌生字段就报错

image.png
image.png

自定义动态映射

如果你想在运行时增加新的字段,你可能会启用动态映射。 然而,有时候,动态映射 规则 可能不太智
能。幸运的是,我们可以通过设置去自定义这些规则,以便更好的适用于你的数据。

日期检测

当 Elasticsearch 遇到一个新的字符串字段时,它会检测这个字段是否包含一个可识别的日期,比如2014-01-01 如果它像日期,这个字段就会被作为 date 类型添加。否则,它会被作为 string 类型添加。有些时候这个行为可能导致一些问题。想象下,你有如下这样的一个文档:
{ “note”: “2014-01-01” }
假设这是第一次识别 note 字段,它会被添加为 date 字段。但是如果下一个文档像这样:
{ “note”: “Logged out” }
这显然不是一个日期,但为时已晚。这个字段已经是一个日期类型,这个 不合法的日期 将会造成一个异常。日期检测可以通过在根对象上设置 date_detection 为 false 来关闭
image.png
使用这个映射,字符串将始终作为 string 类型。如果需要一个 date 字段,必须手动添加。Elasticsearch 判断字符串为日期的规则可以通过 dynamic_date_formats setting 来设置。
image.png

dynamic_templates

使用 dynamic_templates 可以完全控制新生成字段的映射,甚至可以通过字段名称或数据类型来应用不同的映射。每个模板都有一个名称,你可以用来描述这个模板的用途,一个 mapping 来指定映射应该怎样使用,以及至少一个参数 (如 match) 来定义这个模板适用于哪个字段。模板按照顺序来检测;第一个匹配的模板会被启用。例如,我们给 string 类型字段定义两个模板:
es :以 _es 结尾的字段名需要使用 spanish 分词器。
en :所有其他字段使用 english 分词器。
我们将 es 模板放在第一位,因为它比匹配所有字符串字段的 en 模板更特殊:
image.png
image.png
1)匹配字段名以 _es 结尾的字段
2)匹配其他所有字符串类型字段
match_mapping_type 允许你应用模板到特定类型的字段上,就像有标准动态映射规则检测的一样 (例 如 string 或 long)match参数只匹配字段名称,path_match 参数匹配字段在对象上的完整路径,所以 address.*.name将匹配这样的字段
image.png

Query DSL

https://www.elastic.co/guide/en/elasticsearch/reference/7.3/query-dsl.html
Elasticsearch提供了基于JSON的完整查询DSL(Domain Specifific Language 特定域的语言)来定义查询。将查询DSL视为查询的AST(抽象语法树),它由两种子句组成

  • 叶子查询子句

叶子查询子句 在特定域中寻找特定的值,如 match,term或 range查询。

  • 复合查询子句

复合查询子句包装其他叶子查询或复合查询,并用于以逻辑方式组合多个查询(例如 bool或dis_max查询),或更改其行为(例如 constant_score查询)。

  • 基本语法

    1. POST /索引库名/_search
    2. {
    3. "query": {
    4. "查询类型": {
    5. "查询条件":"查询条件值"
    6. }
    7. }
    8. }

    这里的query代表一个查询对象,里面可以有不同的查询属性

  • 查询类型:

例如: match_all , match , term , range 等等

  • 查询条件:查询条件会根据类型的不同

    查询所有(match_all query)

    1. POST /zbc-index/_search
    2. {
    3. "query": {
    4. "match_all": {}
    5. }
    6. }
  • query: 代表查询对象

  • match_all: 代表查询所有

返回结果

  • took:查询花费时间,单位是毫秒
  • time_out:是否超时
  • _shards:分片信息
  • hits:搜索结果总览对象
    • total:搜索到的总条数
    • max_score:所有结果中文档得分的最高分
    • hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
    • _index:索引库
      • _type:文档类型
      • _id:文档id
      • _score:文档得分
      • _source:文档的源数据

        全文搜索(full-text query)

        全文搜索能够搜索已分析的文本字段,如电子邮件正文,商品描述等。使用索引期间应用于字段的同一分析器处理查询字符串。全文搜索的分类很多 几个典型的如下
        匹配搜索(match query)
        全文查询的标准查询,它可以对一个字段进行模糊、短语查询。 match queries 接收text/numerics/dates, 对它们进行分词分析, 再组织成一个boolean查询。可通过operator 指定bool组合操作(or、and 默认是 or )。
        现在,索引库中有2部手机,1台电视; ```shell PUT /lagou-property { “settings”: {}, “mappings”: { “properties”: { “title”: { “type”: “text”, “analyzer”: “ik_max_word” }, “images”: { “type”: “keyword” }, “price”: { “type”: “float” } } } }

POST /lagou-property/_doc/ { “title”: “小米电视4A”, “images”: “http://image.lagou.com/12479122.jpg“, “price”: 4288 }

POST /lagou-property/_doc/ { “title”: “小米手机”, “images”: “http://image.lagou.com/12479622.jpg“, “price”: 2699 }

POST /lagou-property/_doc/ { “title”: “华为手机”, “images”: “http://image.lagou.com/12479922.jpg“, “price”: 5699 }

  1. - **or关系**
  2. match 类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or的关系
  3. ```shell
  4. POST /lagou-property/_search
  5. {
  6. "query":{
  7. "match":{
  8. "title":"小米电视4A"
  9. }
  10. }
  11. }

结果
image.png
在上面的案例中,不仅会查询到电视,而且与小米相关的都会查询到,多个词之间是 or 的关系。

  • and关系

某些情况下,我们需要更精确查找,我们希望这个关系变成 and ,可以这样做

  1. POST /lagou-property/_search
  2. {
  3. "query": {
  4. "match": {
  5. "title": {
  6. "query": "小米电视4A",
  7. "operator": "and"
  8. }
  9. }
  10. }
  11. }

结果
image.png
本例中,只有同时包含 小米 和 电视 的词条才会被搜索到。
短语搜索(match phrase query)
match_phrase 查询用来对一个字段进行短语查询,可以指定 analyzer、slop移动因子

  1. GET /lagou-property/_search
  2. {
  3. "query": {
  4. "match_phrase": {
  5. "title": "小米电视"
  6. }
  7. }
  8. }
  9. GET /lagou-property/_search
  10. {
  11. "query": {
  12. "match_phrase": {
  13. "title": "小米 4A"
  14. }
  15. }
  16. }
  17. GET /lagou-property/_search
  18. {
  19. "query": {
  20. "match_phrase": {
  21. "title": {
  22. "query": "小米 4A",
  23. "slop": 2
  24. }
  25. }
  26. }
  27. }

query_string 查询
Query String Query提供了无需指定某字段而对文档全文进行匹配查询的一个高级查询,同时可以指定在哪些字段上进行匹配。

  1. # 默认 和 指定字段
  2. GET /lagou-property/_search
  3. {
  4. "query": {
  5. "query_string" : {
  6. "query" : "2699"
  7. }
  8. }
  9. }
  10. GET /lagou-property/_search
  11. {
  12. "query": {
  13. "query_string" : {
  14. "query" : "2699",
  15. "default_field" : "title"
  16. }
  17. }
  18. }
  19. # 逻辑查询
  20. GET /lagou-property/_search
  21. {
  22. "query": {
  23. "query_string" : {
  24. "query" : "手机 OR 小米",
  25. "default_field" : "title"
  26. }
  27. }
  28. }
  29. GET /lagou-property/_search
  30. {
  31. "query": {
  32. "query_string" : {
  33. "query" : "手机 AND 小米",
  34. "default_field" : "title"
  35. }
  36. }
  37. }
  38. # 模糊查询
  39. GET /lagou-property/_search
  40. {
  41. "query": {
  42. "query_string" : {
  43. "query" : "大米~1",
  44. "default_field" : "title"
  45. }
  46. }
  47. }
  48. # 多字段支持
  49. GET /lagou-property/_search
  50. {
  51. "query": {
  52. "query_string" : {
  53. "query":"2699",
  54. "fields": [ "title","price"]
  55. }
  56. }
  57. }

多字段匹配搜索(multi match query)
如果你需要在多个字段上进行文本搜索,可用multi_match 。multi_match在 match的基础上支持对多个字段进行文本查询。

  1. GET /lagou-property/_search
  2. {
  3. "query": {
  4. "multi_match" : {
  5. "query":"2699",
  6. "fields": [ "title","price"]
  7. }
  8. }
  9. }

还可以使用*匹配多个字段

  1. GET /lagou-property/_search
  2. {
  3. "query": {
  4. "multi_match" : {
  5. "query":"http://image.lagou.com/12479622.jpg",
  6. "fields": [ "title","ima*"]
  7. }
  8. }
  9. }

词条级搜索(term-level queries)

可以使用term-level queries根据结构化数据中的精确值查找文档。结构化数据的值包括日期范围、IP地址、价格或产品ID。
与全文查询不同,term-level queries不分析搜索词。相反,词条与存储在字段级别中的术语完全匹配。

PUT /book 
{ 
  "settings": {}, 
  "mappings" : { 
    "properties" : { 
      "description" : { 
        "type" : "text", 
        "analyzer" : "ik_max_word" 
      },
      "name" : { 
        "type" : "text", 
        "analyzer" : "ik_max_word"
      },
      "price" : { 
        "type" : "float"
      },
        "timestamp" : { 
          "type" : "date", 
          "format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
    }
  }
}


PUT /book/_doc/1 
{
  "name": "lucene", 
  "description": "Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core. ", "price":100.45, 
  "timestamp":"2020-08-21 19:11:35"
}

PUT /book/_doc/2 
{
  "name": "solr", 
  "description": "Solr is highly scalable, providing fully fault tolerant distributed indexing, search and analytics. It exposes Lucenes features through easy to use JSON/HTTP interfaces or native clients for Java and other languages.", 
  "price":320.45, 
  "timestamp":"2020-07-21 17:11:35" 
}


PUT /book/_doc/3 
{
  "name": "Hadoop", 
  "description": "The Apache Hadoop software library is a framework that allows for the distributed processing of large data sets across clusters of computers using simple programming models.", 
  "price":620.45, 
  "timestamp":"2020-08-22 19:18:35" 
}

PUT /book/_doc/4 
{
  "name": "ElasticSearch", 
  "description": "Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力 的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条 款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜 索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢 迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。", 
  "price":999.99, 
  "timestamp":"2020-08-15 10:11:35" 
}

词条搜索(term query)
term 查询用于查询指定字段包含某个词项的文档

POST /book/_search 
{ 
  "query": { 
    "term" : { 
      "name" : "solr"
    } 
  } 
}

词条集合搜索(terms query)
terms 查询用于查询指定字段包含某些词项的文档

GET /book/_search 
{ 
  "query": { 
    "terms" : { 
      "name" : ["solr", "elasticsearch"]
    } 
  } 
}

范围搜索(range query)

  • gte:大于等于
  • gt:大于
  • lte:小于等于
  • lt:小于
  • boost:查询权重 ```shell GET /book/_search { “query”: { “range” : {
    "price" : { 
      "gte" : 10, 
      "lte" : 200, 
      "boost" : 2.0 
    } 
    
    } } }

GET /book/_search { “query”: { “range” : { “timestamp” : { “gte” : “now-2d/d”, “lt” : “now/d” } } } }

GET book/_search { “query”: { “range” : { “timestamp” : { “gte”: “18/08/2020”, “lte”: “2021”, “format”: “dd/MM/yyyy||yyyy” } } } }

**不为空搜索(exists query)**<br />查询指定字段值不为空的文档。相当 SQL 中的 column is not null
```shell
GET /book/_search 
{ 
  "query": { 
    "exists" : { 
      "field" : "price"
    } 
  }
}

词项前缀搜索(prefifix query)

GET /book/_search 
{ 
  "query": { 
    "prefix" : { 
      "name" : "so" 
    } 
  }
}

通配符搜索(wildcard query)

GET /book/_search 
{ 
  "query": { 
    "wildcard" : { 
      "name" : "so*r"
    }
  }
}
GET /book/_search 
{ 
  "query": { 
    "wildcard": { 
      "name": { 
        "value": "lu*", 
        "boost": 2
      }
    }
  }
}

正则搜索(regexp query)
regexp允许使用正则表达式进行term查询.注意regexp如果使用不正确,会给服务器带来很严重的性能压力。比如.*开头的查询,将会匹配所有的倒排索引中的关键字,这几乎相当于全表扫描,会很慢。因此如果可以的话,最好在使用正则前,加上匹配的前缀。

GET /book/_search 
{ 
  "query": { 
    "regexp":{ "name": "s.*"
    }
  }
}
GET /book/_search 
{ 
  "query": { 
  "regexp":{
    "name":{ 
      "value":"s.*", 
      "boost":1.2
      }
   }
  }
}

模糊搜索(fuzzy query)

GET /book/_search
{ 
  "query": { 
    "fuzzy" : { 
      "name" : { 
        "value": "so", 
        "boost": 1.0, 
        "fuzziness": 2
      }
    }
  }
}

GET /book/_search 
{ 
  "query": { 
    "fuzzy" : { 
      "name" : { 
        "value": "sorl", 
        "boost": 1.0, 
        "fuzziness": 2
      }
    }
  }
}

ids搜索(id集合查询)


GET /book/_search 
{ 
  "query": { 
    "ids" : { 
      "type" : "_doc", 
      "values" : ["1", "3"] 

    } 
  }
}

复合搜索(compound query)

constant_score query
用来包装另一个查询,将查询匹配的文档的评分设为一个常值


GET /book/_search 
{ 
  "query": { 
  "term" : { 
    "description" : "solr"
    } 
  } 
}

GET /book/_search 
{ 
  "query": { 
    "constant_score" : { 
      "filter" : { 
        "term" : { 
          "description" : "solr"
        }
      },
      "boost" : 1.2
    }
  }
}

布尔搜索(bool query)
bool 查询用bool操作来组合多个查询字句为一个查询。 可用的关键字

  • must:必须满足
  • fifilter:必须满足,但执行的是fifilter上下文,不参与、不影响评分
  • should:或
  • must_not:必须不满足,在fifilter上下文中执行,不参与、不影响评分

    POST /book/_search 
    { 
    "query": {
    "bool" : { 
      "must" : { 
        "match" : { 
          "description" : "java" 
        }
      },
      "filter": { 
        "term" : { 
          "name" : "solr" 
          }
        },
          "must_not" : { 
            "range" : { 
              "price" : { 
                "gte" : 200, 
                "lte" : 300 
              }
            } 
          },
          "minimum_should_match" : 1, 
          "boost" : 1.0 
     } 
    } 
    }
    

    minimum_should_match代表了最小匹配精度,如果设置minimum_should_match=1,那么should语句中至少需要有一个条件满足。

    排序

  • 相关性评分排序

默认情况下,返回的结果是按照相关性进行排序的——最相关的文档排在最前。为了按照相关性来排序,需要将相关性表示为一个数值。在 Elasticsearch 中, 相关性得分由一个浮点数进行表示,并在搜索结果中通过 _score 参数返回, 默认排序是 _score 降序,按照相关性评分升序排序如下


POST /book/_search 
{ 
  "query": { 
    "match": {
      "description":"solr"
    } 
  } 
}
POST /book/_search 
{ 
  "query": { 
    "match": {
      "description":"solr"
    } 
  },
  "sort": [ 
    {
      "_score": {
        "order": "asc"
      }
    } 
    ]
}
  • 字段值排序

    POST /book/_search 
    { 
     "query": { 
       "match_all": {}
     },
     "sort": [ 
       {
         "price": {
           "order": "desc"
    
         }
       } 
       ]
    }
    
  • 多级排序

假定我们想要结合使用 price和 _score(得分) 进行查询,并且匹配的结果首先按照价格排序,然后按照相关性得分排序

POST /book/_search 
{ 
  "query":{ 
    "match_all":{}
  },
  "sort": [ 
    { "price": { 
      "order": "desc" 

    }}, 
    { 
      "timestamp": { 
        "order": "desc" 
      }
    }]
}

分页

size:每页显示多少条
from:当前页起始索引, int start = (pageNum - 1) * size

POST /book/_search 
{ 
  "query": { 
    "match_all": {} 
  },
  "size": 2, 
  "from": 0 
}

POST /book/_search 
{ "query": { 
  "match_all": {}
},
"sort": [ 
  {
    "price": {
      "order": "desc"
    }
  }],
  "size": 2, 
  "from": 2 
}

高亮

在使用match查询的同时,加上一个highlight属性:

  • pre_tags:前置标签
  • post_tags:后置标签
  • fifields:需要高亮的字段
    • name:这里声明title字段需要高亮,后面可以为这个字段设置特有配置,也可以空 ```shell POST /book/_search { “query”: { “match”: { “name”: “elasticsearch” } }, “highlight”: { “pre_tags”: ““, “post_tags”: ““, “fields”: [{“name”:{}}] } }

POST /book/_search { “query”: { “match”: { “name”: “elasticsearch” } }, “highlight”: { “pre_tags”: ““, “post_tags”: ““, “fields”: [{“name”:{}},{“description”:{}}] } }

POST /book/_search { “query”: { “query_string” : { “query” : “elasticsearch” } }, “highlight”: { “pre_tags”: ““, “post_tags”: ““, “fields”: [{“name”:{}}, { “description”:{}}] } }

<a name="Rawmn"></a>
## 文档批量操作
**mget 批量查询**<br />单条查询 GET /test_index/_doc/1,如果查询多个id的文档一条一条查询,网络开销太大。
```shell
GET /_mget 
{ "docs" : [ 
  { 
    "_index" : "book", 
    "_id" : 1 
  },
  { 
    "_index" : "book", 
    "_id" : 2 
  } 
  ] 
}

同一索引下批量查询

GET /book/_mget 
{ "docs" : [ 
  { 
    "_id" : 1 
  },
  { 
    "_id" : 2 
  } 
  ] 
}

搜索简化写法

GET /book/_search
{
  "query": {
    "ids": {
      "values": ["1","4"]
    }
  }
}

bulk 批量增删改
Bulk 操作解释将文档的增删改查一些列操作,通过一次请求全都做完。减少网络传输次数。
语法

POST /_bulk {“action”: {“metadata”}} {“data”}

如下操作,删除1,新增5,修改2。

POST /_bulk { “delete”: { “_index”: “book”, “_id”: “1” }} { “create”: { “_index”: “book”, “_id”: “5” }} { “name”: “test14”,”price”:100.99 } { “update”: { “_index”: “book”, “_id”: “2”} } { “doc” : {“name” : “test”} }

功能

  • delete:删除一个文档,只要1个json串就可以了 删除的批量操作不需要请求体
  • create:相当于强制创建 PUT /index/type/id/_create
  • index:普通的put操作,可以是创建文档,也可以是全量替换文档
  • update:执行的是局部更新partial update操作

格式:每个json不能换行。相邻json必须换行。
隔离:每个操作互不影响。操作失败的行会返回其失败信息。
实际用法
bulk请求一次不要太大,否则一下积压到内存中,性能会下降。所以,一次请求几千个操作、大小在几M正好。bulk会将要处理的数据载入内存中,所以数据量是有限的,最佳的数据两不是一个确定的数据,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载。
一般建议是1000-5000个文档,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件(ES的confifig下的elasticsearch.yml)中配置。http.max_content_length: 10mb

Filter DSL

Elasticsearch中的所有的查询都会触发相关度得分的计算。对于那些我们不需要相关度得分的场景下,Elasticsearch以过滤器的形式提供了另一种查询功能,过滤器在概念上类似于查询,但是它们有非常快的执行速度,执行速度快主要有以下两个原因

  • 过滤器不会计算相关度的得分,所以它们在计算上更快一些。
  • 过滤器可以被缓存到内存中,这使得在重复的搜索查询上,其要比相应的查询快出许多。 ```shell POST /book/_search { “query”: { “filtered”: {
    "query": { 
      "match_all": {} 
    },
    "filter": { 
      "range": { 
        "price": { 
          "gte": 200, 
          "lte": 1000 
        } 
      } 
    } 
    
    } } }

5.0 之后的写法

POST /book/_search { “query”: { “bool”: { “must”: { “match_all”: {} }, “filter”: { “range”: { “price”: { “gte”: 200, “lte”: 1000 } } } } } }

<a name="CG8I1"></a>
# 定位非法搜索及原因
在开发的时候,我们可能会写到上百行的查询语句,如果出错的话,找起来很麻烦,Elasticsearch提供了帮助开发人员定位不合法的查询的api _validate
```shell
GET /book/_search?explain 
{ 
  "query": { 
    "match1": { 
      "name": "test"
    } 
  } 
}
使用 validate
GET /book/_validate/query?explain 
{ "query": {
  "match1": { 
    "name": "test"
  }
}
}

聚合分析

聚合分析是数据库中重要的功能特性,完成对一个查询的数据集中数据的聚合计算,如:找出某字段(或计算表达式的结果)的最大值、最小值,计算和、平均值等。Elasticsearch作为搜索引擎兼数据库,同样提供了强大的聚合分析能力。
对一个数据集求最大、最小、和、平均值等指标的聚合,在ES中称为指标聚合 metric而关系型数据库中除了有聚合函数外,还可以对查询出的数据进行分组group by,再在组上进行指标聚合。在 ES 中group by 称为分桶桶聚合 bucketing
Elasticsearch聚合分析语法
在查询请求体中以aggregations节点按如下语法定义聚合分析:
“aggregations”:i
:

7
,”‘meta”:f
[]]?
,”aggregations”
i[]+]]?!—在聚合里面在定义子聚合
[,”aggregation_name-2>”:f…j!—聚合的名字
image.png
*说明:
aggregations 也可简写为 aggs

指标聚合

max min sum avg

示例一:查询所有书中最贵的

GET /book/_search
{
  "size":0,
  "aggs": {
    "max_price": {
      "max": {
        "field": "price"
      }
    }
  }
}

文档计数count

统计price大于100的文档数量

GET /book/_count
{
 "query": {
   "range": {
     "price": {
       "gt": 100
     }
   }
 }
}

value_count 统计某字段有值的文档数

GET /book/_search
{
  "aggs": {
    "price_count": {
      "value_count": {
        "field": "price"
      }
    }
  }
}

cardinality值去重计数 基数

POST /book/_search?size=0 
{ 
  "aggs": { 
    "_id_count": { 
      "cardinality": {
        "field": "_id" 
      }
    },
    "price_count": { 
      "cardinality": { 
        "field": "price" 
      }
    } 
  } 
}

stats 统计 count max min avg sum 5个值

POST /book/_search?size=0
{ 
  "aggs": { 
    "price_stats": { 
      "stats": { 
        "field": "price" 
      }
    }
  }
}

Extended stats
高级统计,比stats多4个统计结果: 平方和、方差、标准差、平均值加/减两个标准差的区间

POST /book/_search?size=0
{ 
  "aggs": { 
    "price_stats": { 
      "extended_stats": { 
        "field": "price" 
      }
    }
  }
}

Percentiles 占比百分位对应的值统计

POST /book/_search?size=0
{ 
  "aggs": { 
    "price_stats": { 
      "percentiles": { 
        "field": "price" 
      }
    }
  }
}

指定分位值

POST /book/_search?size=0
{ 
  "aggs": { 
    "price_stats": { 
      "percentiles": { 
        "field": "price",
        "percents" : [75, 99, 99.9]
      }
    }
  }
}

Percentiles rank 统计值小于等于指定值的文档占比
统计price小于100100200的文档的占比

POST /book/_search?size=0 
{ 
  "aggs": { 
    "gge_perc_rank": { 
      "percentile_ranks": { 
        "field": "price", 
        "values": [ 100,200 ] 
      } 
    } 
  } 
}

桶聚合

Bucket Aggregations,桶聚合。
它执行的是对文档分组的操作(与sql中的group by类似),把满足相关特性的文档分到一个桶里,即桶分,输出结果往往是一个个包含多个文档的桶(一个桶就是一个group)
bucket:一个数据分组
metric:对一个数据分组执行的统计

POST /book/_search
{
  "size": 0,
  "aggs": {
    "group_by_price": {
      "range": {
        "field": "price",
        "ranges": [
          {
            "from": 0,
            "to": 200
          },
          {
            "from": 200,
            "to":400
          },
          {
            "from": 400,
            "to": 1000
          }
        ]
      },
      "aggs": {
        "average_price": {
          "avg": {
            "field": "price"
          }
        },
        "count_price": { //值的个数统计
          "value_count": {
            "field": "price"
          }
        }
      }
    }
  }
}

实现having 效果


POST /book/_search 
{ 
  "size": 0, 
  "aggs": { 
    "group_by_price": { 
      "range": { 
        "field": "price", 
        "ranges": [ 
          { "from": 0, "to": 200 },
          { "from": 200, "to": 400 },
          { "from": 400, "to": 1000 } 
          ] 
      },
      "aggs": { 
        "average_price": { 
          "avg": { 
            "field": "price" 
          } 
        },
        "having": { 
          "bucket_selector": { 
            "buckets_path": { 
              "avg_price": "average_price" 
            },
            "script": { 
              "source": "params.avg_price >= 200 " 
            }
          } 
        } 
      } 
    } 
  } 
}