盒子
盒子
文章目录
  1. 1. 基本操作
    1. 1.1 索引
      1. 1.1.1 查看索引相关信息
      2. 1.1.2 创建索引
      3. 1.1.3 删除索引
      4. 1.1.4 修改Mapping
      5. 1.1.5 设置别名
      6. 1.1.6 查询别名
    2. 1.2 文档
      1. 1.2.1 新增文档
      2. 1.2.2 修改文档
      3. 1.2.3 局部修改文档
      4. 1.2.4 删除文档
      5. 1.2.5 根据id查找文档
      6. 1.2.6 查找返回文档一部分
  2. 2. 结构化查询 Query DSL
    1. 2.1 查询
      1. 2.1.1 term 精确查询
      2. 2.1.2 match 模糊查询
      3. 2.1.3 range 范围查询
      4. 2.1.4 exists 空值查询
      5. 2.1.5 nested 集合查询
      6. 2.1.5 bool 多条件查询
    2. 2.2 排序
      1. 2.2.1 sort 排序
      2. 2.2.2 from size 分页
      3. 2.2.3 count 数量
    3. 2.3 聚合 aggs 类似sql的group by
      1. 2.3.1 主要概念
      2. 2.3.2 语法结构
      3. 2.3.3 例子
        1. 2.3.3.1 terms 按字段聚合
        2. 2.3.3.2 filter 自定义分组聚合
        3. 2.3.3.3 range 按范围聚合
        4. 2.3.3.4 子聚合 求平均值
        5. 2.3.3.5 多个filed聚合
  3. 3. 子索引
    1. 3.1 子索引和nested的区别
    2. 3.2 父子索引的创建
      1. 3.2.1 创建Mapping
      2. 3.2.2 插入父文档
      3. 3.2.3 插入子文档
    3. 3.3 查询
      1. 3.3.1 parent_id 基于父文档ID查询所有子文档
      2. 3.3.2 has_parent 查询符合条件的父文档的所有子文档
      3. 3.3.3 has_child 查询符合条件的子文档的所有父文档
  4. 4. Painless Scripting
    1. 4.1 语法
      1. 4.1.1 访问某个field
    2. 4.2 例子
      1. 4.2.1 插入、更新文档
        1. 4.2.1.1 修改文档
        2. 4.2.1.2 修改文档时自定义参数
        3. 4.2.1.3 增加query条件、脚本判断 修改文档
        4. 4.2.1.4 集合增加、删除元素
        5. 4.2.1.5 nested 增加、删除、修改
      2. 4.2.2查询文档
        1. 4.2.2.1 使用脚本增加筛选条件
        2. 4.2.2.2 使用脚本自定义返回字段
        3. 4.2.2.3 使用脚本排序
        4. 4.2.2.4 使用脚本聚合
  5. 5. Ingest pipelines

Elasticsearch 6.2.2的Restful API 常用操作

文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

1. 基本操作

1.1 索引

1.1.1 查看索引相关信息

request
1
2
3
4
// 查询 索引的 mapping和setting信息  
GET /{index}
// 查询索引order的信息
GET /order

1.1.2 创建索引

request
1
2
3
4
5
6
7
8
9
// 创建索引 
PUT /{index}
// 创建索引order
PUT /order
{
"mappings": {
.......
}
}

1.1.3 删除索引

request
1
2
3
4
// 删除索引 
DELETE /{index}
// 删除索引order
DELETE /order

1.1.4 修改Mapping

request
1
2
3
4
5
6
7
8
9
10
11
// 修改mapping
PUT /{index}/{type}/_mapping
// order索引新增字段age
PUT /order/table/_mapping
{
"properties": {
"age": {
"type": "long"
}
}
}

1.1.5 设置别名

request
1
2
3
4
5
6
7
8
9
10
11
12
// 索引order_v4设置别名 order
PUT _aliases
{
"actions": [
{
"add": {
"index": "order_v4",
"alias": "order"
}
}
]
}

1.1.6 查询别名

request
1
2
3
4
// 查询所有索引的别名
GET _alias
// 根据索引名或别名是order的别名信息
GET order/_alias

1.2 文档

1.2.1 新增文档

request
1
2
3
4
5
6
// 新增
POST /{index}/{type}/{_id}
{
"id":1,
"name":"test"
}

1.2.2 修改文档

request
1
2
3
4
5
6
// 修改
POST /{index}/{type}/{_id}
{
"id":1,
"name":"test2"
}

1.2.3 局部修改文档

request
1
2
3
4
5
// 将ID为1的文档的name字段改成test2
POST /{index}/{type}/{_id}/_update
{
"doc": { "name":"test2" }
}

1.2.4 删除文档

request
1
2
3
4
5
// 根据id删除
DELETE /{index}/{type}/{_id}

// 删除订单1681323982163296643
DELETE order/table/1681323982163296643

1.2.5 根据id查找文档

request
1
2
3
4
5
// 根据id查找
GET /{index}/{type}/{_id}

// 查询订单1681323982163296643
GET order/table/1681323982163296643

1.2.6 查找返回文档一部分

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//  只返回order的 id和name
POST order/_search
{
"_source": ["id","name"]
}

// 只返回order的 id和name
POST order/_search
{
"_source": {
"includes": [ "id", "name" ]
}
}

// 不返回order的 name
POST order/_search
{
"_source": {
"excludes": ["name"]
}
}

2. 结构化查询 Query DSL

2.1 查询

2.1.1 term 精确查询

  • term:精确查询, 主要用于精确匹配,比如数字,日期,布尔值或 not_analyzed 的字符串
  • trems : 跟 term 有点类似,但 terms 允许指定多个匹配条件
request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 根据手机号精确查询
POST /order/_search
{
"query": {
"term": {
"userMobile": "13126820209"
}
}
}

// 查询多个手机号
POST /order/_search
{
"query": {
"terms": {
"userMobile": [
"13126820209",
"15232181101"
]
}
}
}

2.1.2 match 模糊查询

  • match 和 term的区别
    • keyword: 在写入时,将整个值插入到倒排索引中,不进行分词。
      • term不会分词。而keyword字段也不分词。需要完全匹配才可。
      • match会被分词,而keyword不会被分词,match的需要跟keyword的完全匹配可以。
    • text: 在写入时,对写入的值进行分词,然后一一插入到倒排索引。
      • 因为text字段会分词,而term不分词,所以term查询的条件必须是text字段分词后的某一个。
      • match分词,text也分词,只要match的分词结果和text的分词结果有相同的就匹配
  • multi_match 允许同时搜索多个字段

    request
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // 根据手机号查询
    POST /order/_search
    {
    "query": {
    "match": {
    "userMobile": "13126820209"
    }
    }
    }

    // 查询cityName 或 ipCityName 是武汉的订单
    POST /order/_search
    {
    "query": {
    "multi_match": {
    "query": "武汉",
    "fields": ["cityName","ipCityName"]
    }
    }
    }
  • match_phrase 称为短语搜索,要求所有的分词必须同时出现在文档中,同时位置必须紧邻一致。

    2.1.3 range 范围查询

  • range允许我们按照指定范围查找一批数据
    • gt :: 大于
    • gte :: 大于等于
    • lt :: 小于
    • lte :: 小于等于
request
1
2
3
4
5
6
7
8
9
10
11
12
// 查询 createTime 大于等于 1523111285000  ,小于等于 1523111286000 的订单
POST /order/_search
{
"query": {
"range": {
"createTime": {
"gte": 1523111285000,
"lte": 1523111286000
}
}
}
}

2.1.4 exists 空值查询

exists 用于查找文档中是否包含指定字段 对应sql中的 not null

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// vendorId1701cityId有值的订单
POST /order/_search
{
"query": {
"exists":{
"field":"vendorId1701cityId"
}
}
}

// vendorId1701cityId 没有值的订单
POST /order/_search
{
"query": {
"bool": {
"must_not": [
{
"exists": {
"field":"vendorId1701cityId"
}
}
]
}
}
}

2.1.5 nested 集合查询

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 查找 members.vendorName是张云天的订单
POST /order/_search
{
"query": {
"nested": {
"path": "members",
"query": {
"match": {
"members.vendorName" : "张云天"
}
}
}
}
}

// 查找 members.vendorName 是张云天 并且 members.createVendorTime 是1651381826000 的订单
POST /order/_search
{
"query": {
"nested": {
"path": "members",
"query": {
"bool": {
"must": [
{
"match": {
"members.vendorName": "张云天"
}
},
{
"match": {
"members.createVendorTime": 1651381826000
}
}
]
}
}
}
}
}

2.1.5 bool 多条件查询

  • must 多个查询条件的完全匹配,相当于 and 。
  • must_not 多个查询条件的相反匹配,相当于 not 。
  • should 至少有一个查询条件匹配, 相当于 or 。
  • filter 过滤 必须匹配,不贡献算分

    2.2 排序

    2.2.1 sort 排序

    request
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    // 结果集会先用第一排序字段来排序,当用用作第一字段排序的值相同的时候, 然后再用第二字段对第一排序值相同的文档进行排序
    POST /order/_search
    {
    "query": {
    "term": {
    "cityName": "北京"
    }
    },
    "sort": [
    {
    "createTime": {
    "order": "desc"
    },
    "updateTime": {
    "order": "desc"
    }
    }
    ]
    }

    2.2.2 from size 分页

    request
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    POST /order/_search
    {
    "query": {
    "term": {
    "cityName": "北京"
    }
    },
    "from": 0,
    "size": 20
    }

2.2.3 count 数量

request
1
2
// 查询数量
GET order/_count

2.3 聚合 aggs 类似sql的group by

2.3.1 主要概念

  • 桶(Buckets):满足特定条件的文档的集合,类似于SQL中的group by。

    • Bucket Aggregations常用的有terms、range、filter、地理距离、geo、ip范围、嵌套nested等
  • 指标(Metrics):对桶内的文档进行统计计算,类似于SQL中的count()、sum()、max()等聚合函数。

    • Metric Aggregations常用的有min、max、avg、sum、cardinality等

2.3.2 语法结构

request
1
2
3
4
5
6
7
8
9
10
11
{
"aggregations" : {
"<aggregation_name>" : {
"<aggregation_type>" : {
<aggregation_body>
}
[,"aggregations" : { [<sub_aggregation>]+ } ]? // 嵌套聚合查询,支持多层嵌套
}
[,"<aggregation_name_2>" : { ... } ]* // 多个聚合查询,每个聚合查询取不同的名字
}
}
  • aggregations - 代表聚合查询语句,可以简写为aggs
  • <aggregation_name> - 代表一个聚合计算的名字,可以随意命名,因为ES支持一次进行多次统计分析查询,后面需要通过这个名字在查询结果中找到我们想要的计算结果。
  • <aggregation_type> - 聚合类型,代表我们想要怎么统计数据,主要有两大类聚合类型,桶聚合和指标聚合,这两类聚合又包括多种聚合类型,例如:指标聚合:sum、avg, 桶聚合:terms、Date histogram等等。
  • <aggregation_body> - 聚合类型的参数,选择不同的聚合类型,有不同的参数。
  • aggregation_name_2 - 代表其他聚合计算的名字,意思就是可以一次进行多种类型的统计。

2.3.3 例子

2.3.3.1 terms 按字段聚合

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 对应sql  select cityName,count(cityName) from table group by cityName
POST /order/_search
{
"aggs": {
"cityGroup": {
"terms": { // 按cityName聚合
"field": "cityName"
}
}
}
}


// 查询结果
{
。。。。
"aggregations": {
"cityGroup": {
"doc_count_error_upper_bound": 1029,
"sum_other_doc_count": 118083,
"buckets": [
{
"key": "北京",
"doc_count": 320859
},
{
"key": "上海",
"doc_count": 132995
},
。。。
]
}
}
}

2.3.3.2 filter 自定义分组聚合

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 按filter聚合
POST /order/_search
{
"aggs": {
"testAggs": {
"filters": {
"filters": {
"北京统计": {"match":{"cityName":"北京"}},
"上海统计": {"match":{"cityName":"上海"}}
}
}
}
}
}

//查询结果
{
。。。。
"aggregations": {
"testAggs": {
"buckets": {
"上海": {
"doc_count": 132995
},
"北京": {
"doc_count": 320862
}
}
}
}
}

2.3.3.3 range 按范围聚合

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 按范围聚合
POST /order/_search
{
"aggs": {
"testRange":{
"range": {
"field": "mlPrice",
"ranges": [
{ "to" : 50 },
{ "from" : 50, "to" : 100 },
{ "from" : 100 }
]
}
}
}
}

//查询结果
{
。。。。
"aggregations": {
"testRange": {
"buckets": [
{
"key": "*-50.0",
"to": 50,
"doc_count": 873767
},
{
"key": "50.0-100.0",
"from": 50,
"to": 100,
"doc_count": 0
},
{
"key": "100.0-*",
"from": 100,
"doc_count": 15820
}
]
}
}
}

2.3.3.4 子聚合 求平均值

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// 对应sql  select cityName,count(cityName),avg(mlPrice) from table group by cityName
POST /order/_search
{
"aggs": {
"cityGroup": {
"terms": { // 按cityName聚合
"field": "cityName"
},
"aggs": { // 嵌套聚合
"avg_score": {
"avg": { // 求平均数
"field": "mlPrice"
}
}
}
}
}
}


//查询结果
{
。。。。
"aggregations": {
"cityGroup": {
"doc_count_error_upper_bound": 1029,
"sum_other_doc_count": 118086,
"buckets": [
{
"key": "北京",
"doc_count": 320861,
"avg_score": {
"value": 54198.74264556926
}
},
{
"key": "上海",
"doc_count": 132995,
"avg_score": {
"value": 53444.499958645065
}
},
。。。。
]
}
}
}

2.3.3.5 多个filed聚合

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// 对应sql  select cityName,community,count(1),avg(mlPrice) from table group by cityName,community
POST /order/_search
{
"aggs": {
"cityGroup": {
"terms": {
"script": "doc['cityName'].values+'-'+doc['community'].values",
"size": 20 //返回条数
},
"aggs": {
"avg_score": {
"avg": {
"field": "mlPrice"
}
}
}
}
}
}

//查询结果
{
。。。。
"aggregations": {
"cityGroup": {
"doc_count_error_upper_bound": 1479,
"sum_other_doc_count": 445778,
"buckets": [
{
"key": "[]-[]",
"doc_count": 730484,
"avg_score": {
"value": -2503.5909282827674
}
},
{
"key": "[北京]-[]",
"doc_count": 161802,
"avg_score": {
"value": -39.28776529338327
}
},
{
"key": "[北京]-[朝阳区]",
"doc_count": 7962,
"avg_score": {
"value": -2849.4228836975635
}
},
{
"key": "[上海]-[浦东新区]",
"doc_count": 4646,
"avg_score": {
"value": 42442.208136031
}
}
。。。。
]
}
}
}

3. 子索引

3.1 子索引和nested的区别

nested parent/child
插入、更新 更新时需要更新整个文档 父子文档可以独立更新
查询 文档存储在一起,读取性能高 父子文档单独存储,互不影响。但是为了维护join的关系,需要占用额外的内容,读取性能略差。
适用场景 子文档偶尔更新、查询为主 适用于更新频繁的情况,且子文档的数量远远超过父文档的数量

3.2 父子索引的创建

3.2.1 创建Mapping

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 修改mapping,定义父文档 order_v1  定义三个子文档分别是 order_log  order_dg_info  order_zy_info
PUT /{index}/{type}/_mapping
{
"properties": {
"order_join_relation": { // 定义一个字段名称
"type": "join", // 类型为join
"relations": {
"order_v1": [ // 父文档值
"order_log", // 子文档值
"order_dg_info",
"order_zy_info"
]
}
}
}
}

3.2.2 插入父文档

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 两种写法都可以

POST /{index}/{type}/{_id}
{
"id":1,
"name":"test2",
"order_join_relation":{
"name" : "order_v1"
}
}



POST /{index}/{type}/{_id}
{
"id":1,
"name":"test2",
"order_join_relation": "order_v1"
}

3.2.3 插入子文档

request
1
2
3
4
5
6
7
8
9
POST /{index}/{type}/{_id}?routing={parentID}
{
"id":1,
"name":"test2",
"order_join_relation":{
"name" : "order_log",
"parent":{parentID}
}
}

3.3 查询

3.3.1 parent_id 基于父文档ID查询所有子文档

request
1
2
3
4
5
6
7
8
9
POST order/_search
{
"query":{
"parent_id": { // 关键字
"type":"order_log", // 要查询的子文档类型
"id":"5" // 父文档id
}
}
}

3.3.2 has_parent 查询符合条件的父文档的所有子文档

request
1
2
3
4
5
6
7
8
9
10
11
12
13
POST order/_search
{
"query": {
"has_parent": { // 关键字
"parent_type": "order_v1", // 父文档类型
"query": { // 父文档查询条件
"match": {
"name": "test2"
}
}
}
}
}

3.3.3 has_child 查询符合条件的子文档的所有父文档

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST order/_search
{
"query": {
"has_child": { // 关键字
"type": "order_log", // 子文档类型
"min_children": 1, // 符合条件的子文档必须要1个以上,才返回父文档
"query": { // 子文档查询条件
"match": {
"name": "test2"
}
}
}
}
}

4. Painless Scripting

4.1 语法

官方文档 https://www.elastic.co/guide/en/elasticsearch/painless/master/painless-guide.html

1
2
3
4
5
"script": {
"lang": "...",
"source" | "id": "...",
"params": { ... }
}
  • lang: 定义脚本使用的语言, 默认painless
  • source, id: 脚本的主体, source后面跟着内联的脚本代码, id后面跟着脚本的id, 具体代码存在于脚本id对应的代码中
  • params: 定义一些变量的值, 使用params可以减少脚本的编译次数. 因为如果变量的值硬编码到代码中, 每次进行变量值得更改都会对脚本进行重新编译. 使用params则不会重新编译脚本.

4.1.1 访问某个field

  • update / update_by_query / reindex 场景,使用:ctx._source.XXX;
  • search和聚合场景,使用:doc[‘value’]。
  • ingest 场景,使用:ctx.XXX;
  • 其他场景 https://www.elastic.co/guide/en/elasticsearch/painless/master/painless-contexts.html

    4.2 例子

    4.2.1 插入、更新文档

    4.2.1.1 修改文档

    request
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    // 对应sql update order set name = concat(name,age) where id = 1
    POST order/table/1/_update
    {
    "script":{
    "source":"ctx._source.name+= ctx._source.age",
    "lang":"painless"
    }
    }

4.2.1.2 修改文档时自定义参数

request
1
2
3
4
5
6
7
8
9
// 对应sql   update order set age = concat(age,"4") where id = 1
POST order/table/1/_update
{
"script":{
"source":"ctx._source.age+= params.count",
"lang":"painless",
"params":{"count":4}
}
}

4.2.1.3 增加query条件、脚本判断 修改文档

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 对应sql   update order set age = '123' where age = '34'
POST order/table/_update_by_query
{
"script":{
"lang":"painless",
"source":"ctx._source.age=123"
},
"query":{
"term":{
"age":"34"
}
}
}

// 对应sql update order set age = '456' where age = '123'
POST order/table/_update_by_query
{
"script":{
"lang":"painless",
"source":"if (ctx._source.age == '123') {ctx._source.age = '456'}"
}
}

4.2.1.4 集合增加、删除元素

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 增加tags的元素
// 注意:tags元素需要已经存在,并且类型是array。否则会异常
POST order/table/1/_update
{
"script": {
"source": "ctx._source.tags.add(params.tag)",
"lang": "painless",
"params": {
"tag": "blue"
}
}
}


// 删除tags的元素
POST order/table/1/_update
{
"script": {
"source": "if (ctx._source.tags.contains(params.tag)) { ctx._source.tags.remove(ctx._source.tags.indexOf(params.tag)) }",
"lang": "painless",
"params": {
"tag": "blue"
}
}
}

4.2.1.5 nested 增加、删除、修改

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 样例数据
{
"detail": [
{
"name": "美团",
"nid": 1200
}
],
"id": 1
}

// 增加
POST /order/table/1/_update
{
"script": {
"lang": "painless",
"source": "ctx._source.detail.add(params.data);",
"params": {
"data": {
"name": "百度",
"nid": 1300
}
}
}
}



// 修改
POST /order/table/1/_update
{
"script": {
"lang": "painless",
"source": "for(e in ctx._source.detail){if (e.name == params.name) {e.nid = params.nid;}}",
"params": {
"name": "百度",
"nid": 1500
}
}
}

// 删除
POST /order/table/1/_update
{
"script": {
"lang": "painless",
"source": "ctx._source.detail.removeIf(it -> it.nid ==params.nid);if(ctx._source.detail.length == 0){ctx.op='delete'}",
"params":{
"nid": 1200
}
}
}

4.2.2查询文档

4.2.2.1 使用脚本增加筛选条件

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 查询userMobile是135开头的订单
POST order/_search
{
"query": {
"bool": {
"filter": {
"script": {
"script": {
"source":"doc['userMobile'] != null && doc['userMobile'].value!= null && doc['userMobile'].value.startsWith('135')"
}
}
}
}
}
}

4.2.2.2 使用脚本自定义返回字段

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 自定义字段
POST order/_search
{
"script_fields": {
"shortOrderId-test": {
"script": {
"lang":"painless",
"source":"doc['shortOrderId'].value * params.num",
"params": {
"num":100
}
}
}
}
}

4.2.2.3 使用脚本排序

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 查询userMobile是135开头的订单
POST order/_search
{
"sort": {
"_script":{
"type":"number",
"order":"desc",
"script":{
"lang":"painless",
"source":"doc['sgSrAllPrice'].value + doc['onlyDgFormMlPrice'].value"
}
}
}
}

4.2.2.4 使用脚本聚合

request
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 对应sql  select cityName,community,count(1),avg(mlPrice) from table group by cityName,community

POST order/_search
{
"aggs": {
"cityGroup": {
"terms": {
"script": "doc['cityName'].values+'-'+doc['community'].values",
"size": 20 //返回条数
},
"aggs": {
"avg_score": {
"avg": {
"field": "mlPrice"
}
}
}
}
}
}

//查询结果
{
。。。。
"aggregations": {
"cityGroup": {
"doc_count_error_upper_bound": 1479,
"sum_other_doc_count": 445778,
"buckets": [
{
"key": "[]-[]",
"doc_count": 730484,
"avg_score": {
"value": -2503.5909282827674
}
},
{
"key": "[北京]-[]",
"doc_count": 161802,
"avg_score": {
"value": -39.28776529338327
}
},
{
"key": "[北京]-[朝阳区]",
"doc_count": 7962,
"avg_score": {
"value": -2849.4228836975635
}
},
{
"key": "[上海]-[浦东新区]",
"doc_count": 4646,
"avg_score": {
"value": 42442.208136031
}
}
。。。。
]
}
}
}

5. Ingest pipelines

文档 https://www.elastic.co/guide/en/elasticsearch/reference/master/ingest.html