1. 程式人生 > 實用技巧 >es建立普通索引以及各種查詢

es建立普通索引以及各種查詢

建立索引

  • 建立普通索引:
PUT /my_index
{
  "settings": {
      "index": {
        "number_of_shards": "5",
        "number_of_replicas": "1"
      }
    }
}
  • 查詢索引屬性
GET /my_index

結果:
{
  "my_index": {
    "aliases": {},
    "mappings": {},
    "settings": {
      "index": {
        "creation_date": "1599903519568",
        "number_of_shards": "5",    主分片
        "number_of_replicas": "1",  副分片
        "uuid": "2WW-BXNxTFafswb0oURYjQ",
        "version": {
          "created": "5060999"
        },
        "provided_name": "my_index"
      }
    }
  }
}
  • 建立type
PUT /my_index/my_type/_mapping
{
  "properties": {
    "id":{
      "type": "integer"
    },
    "name":{
      "type": "text"
    },
    "age":{
      "type": "integer"
    },
    "productID":{
      "type": "text"
    },
    "createtime":{
      "type": "date",
      "format": "yyyy-MM-dd HH:mm:ss"
    }
  }
}
  • 檢視type
GET /my_test/my_type/_mapping

結果:
{
  "my_index": {
    "mappings": {
      "my_type": {
        "properties": {
          "age": {
            "type": "integer"
          },
          "createtime": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss"
          },
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "text"
          },
          "productID": {
            "type": "text"
          }
        }
      }
    }
  }
}
  • 新增資料
PUT /my_index/my_type/_bulk
{ "index": { "_id":1}}
{ "id":1,"name": "張三","age":18,"createtime":"2020-09-01 16:16:16","productID":"XHDK-A-1293-#fJ3"}
{ "index": { "_id": 2}}
{ "id":2,"name": "張四","age":20,"createtime":"2020-08-01 16:16:16","productID":"KDKE-B-9947-#kL5"}
{ "index": { "_id": 3}}
{"id":3, "name": "李四","age":22,"createtime":"2020-09-02 16:16:16","productID":"JODL-X-1937-#pV7"}

--  沒有手動插入對映,因此es會為我們自動建立對映,這就意味著只要是文字就會為我們使用分詞器分詞。

各種查詢

空查詢(不推薦)

GET _search   查詢所有索引下的資料

GET /my_index/_search    查詢my_index索引下的所有資料

GET /my_index/my_type/_search    查詢my_index索引下my_type下的所有資料

精確查詢

當進行精確值查詢時, 我們會使用過濾器(filters)。過濾器很重要,因為它們執行速度非常快,不會計算相關度(直接跳過了整個評分階段)而且很容易被快取。我們會在本章後面的 過濾器快取 中討論過濾器的效能優勢,不過現在只要記住:請儘可能多的使用過濾式查詢。

term查詢:

  • elasticsearch對這個搜尋的詞語不做分詞,用於精確匹配,比如Id,數值型別的查詢。
  • 可以用它處理數字(numbers)、布林值(Booleans)、日期(dates)以及不被分析的文字(text)。

查詢數值:

  • 使用constant_score查詢以非評分模式來執行 term 查詢並以一作為統一評分,這樣返回的結果的評分全部是1
  • 使用constant_score將term轉化為過濾器查詢
GET /my_index/my_type/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term":{
          "age": 20
        }
      }
    }
  }
}

結果:
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "2",
        "_score": 1,
        "_source": {
          "id": 2,
          "name": "張四",
          "age": 20,
          "createtime": "2020-08-01 16:16:16",
          "productID": "KDKE-B-9947-#kL5"
        }
      }
    ]
  }
}

查詢文字

本文是怎樣分詞的?

  • 大寫字母轉為小寫字母
  • 複數變為單數
  • 去掉特殊符號
GET /my_index/my_type/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term":{
          "productID": "KDKE-B-9947-#kL5"
        }
      }
    }
  }
}

查詢結果:
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

查詢無結果?

由於term是精確查詢,但是在查詢文字的時候,很有可能這個文字已經進行了分詞,但是term查詢的時候搜尋的詞不分詞,因此可能兩個文字明明是一樣的,但是卻匹配不上,我們可以使用分詞分析器看看這個productID如何實現分詞的,如下:

GET /my_index/_analyze
{
  "field": "{productID}",
  "text": "KDKE-B-9947-#kL5"
}

查詢結果:
{
  "tokens": [
    {
      "token": "kdke",
      "start_offset": 0,
      "end_offset": 4,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "b",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "9947",
      "start_offset": 7,
      "end_offset": 11,
      "type": "<NUM>",
      "position": 2
    },
    {
      "token": "kl5",
      "start_offset": 13,
      "end_offset": 16,
      "type": "<ALPHANUM>",
      "position": 3
    }
  ]
}

從上面查詢結果來看:
1、將特殊符號-分詞時自動去掉了
2、大寫字母全部轉為小寫
解決方案:

如果需要使用term精確匹配查詢文字,那麼這個文字就不能使用分詞器分詞,因此需要手動建立索引的對映(mapping),如下:

DELETE my_index    刪除索引

PUT /my_index                  重新建立索引
{
  "settings": {
      "index": {
        "number_of_shards": "5",
        "number_of_replicas": "1"
      }
    }
}

PUT /my_index/my_type/_mapping
{
  "properties": {
    "id":{
      "type": "integer"
    },
    "name":{
      "type": "text"
    },
    "age":{
      "type": "integer"
    },
    "productID":{                  重新指定欄位索引對映,文字keyword型別是不被分詞的
      "type": "text",
      "fields": {
        "keyword":{
          "type": "keyword"
        }
      }
    },
    "createtime":{
      "type": "date",
      "format": "yyyy-MM-dd HH:mm:ss"
    }
  }
}


重新加入資料後就能精確匹配到資訊了

GET /my_index/my_type/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term":{
          "productID.keyword": "KDKE-B-9947-#kL5"    
        }
      }
    }
  }
}

terms查詢

  • 對於多個關鍵字的查詢,假設我們需要查詢age在18,20,22中的其中一個即可,那麼需要使用terms指定多組值。
  • 精確查詢,不會使用分詞器
GET /my_index/my_type/_search
{
  "query": {
    "terms": {
      "age": [
        18,
        20,
        22
      ]
    }
  }
}

指定文件數量(from,size)
  • 假設我們需要對前兩個文件進行查詢,那麼可以使用from和size指定文件的數量,如下:
GET /my_index/my_type/_search
{
  "from": 0,  從第一個文件
  "size": 2,  查詢兩個文件
 "query": {
   "terms": {
     "age": [
        18,
        20,
        22
      ]
   }
 } 
} 
返回指定欄位_source
  • 在使用查詢的時候預設返回的是全部的欄位,那麼我們可以使用_source指定返回的欄位
GET /my_index/my_type/_search
{
  "from": 0,
  "size": 2, 
  "_source": ["id","name","age"], 
 "query": {
   "terms": {
     "age": [
        18,
        20,
        22
      ]
   }
 } 
}
排除不返回的欄位exclude
GET /my_index/my_type/_search
{
  "from": 0,
  "size": 2, 
  "_source": {
      "includes": ["id","name","age"],  返回欄位
      "excludes":["productID"]          不返回的欄位
    }, 
 "query": {
   "terms": {
     "age": [
        18,
        20,
        22
      ]
   }
 } 
} 

match查詢

  • match查詢和term查詢相反,知道分詞器的存在,會對搜尋的詞語進行分詞。
  • 上面使用match查詢productId的時候,因為term不知道分詞器的存在,因此查詢不到,但是我們使用match查詢可以匹配到,如下:
GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "productID": "KDKE-B-9947-#kL5"
    }
  }
}

查詢結果:
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.2876821,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "2",
        "_score": 0.2876821,
        "_source": {
          "id": 2,
          "name": "張四",
          "age": 20,
          "createtime": "2020-08-01 16:16:16",
          "productID": "KDKE-B-9947-#kL5"
        }
      }
    ]
  }
}
  • 比如我們查詢姓名為張三的資料
GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "name": "張三"  會對這個短語先進行分詞之後再去查詢
    }
  }
}

查詢結果:
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.51623213,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "1",
        "_score": 0.51623213,
        "_source": {
          "id": 1,
          "name": "張三",
          "age": 18,
          "createtime": "2020-09-01 16:16:16",
          "productID": "XHDK-A-1293-#fJ3"
        }
      },
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "2",
        "_score": 0.25811607,
        "_source": {
          "id": 2,
          "name": "張四",
          "age": 20,
          "createtime": "2020-08-01 16:16:16",
          "productID": "KDKE-B-9947-#kL5"
        }
      }
    ]
  }
}

分析:match查詢會將查詢語句先按標準的分詞器分析後,根據分析後的單詞去匹配索引。
GET /my_index/_analyze
{
  "text": "張三"
}

分詞結果:
{
  "tokens": [
    {
      "token": "張",
      "start_offset": 0,
      "end_offset": 1,
      "type": "<IDEOGRAPHIC>",
      "position": 0
    },
    {
      "token": "三",
      "start_offset": 1,
      "end_offset": 2,
      "type": "<IDEOGRAPHIC>",
      "position": 1
    }
  ]
}

match_phrase(短語匹配)

  • 類似 match 查詢, match_phrase 查詢首先將查詢字串解析成一個詞項列表,然後對這些詞項進行搜尋,但只保留那些包含 全部 搜尋詞項,且 位置 與搜尋詞項相同的文件。 比如對於 quick fox 的短語搜尋可能不會匹配到任何文件,因為沒有文件包含的 quick 詞之後緊跟著 fox
  • 位置順序必須一致
GET /my_index/my_type/_search
{
  "query": {
    "match_phrase": {
      "name": "張三"
    }
  }
}

查詢結果:
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.51623213,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "1",
        "_score": 0.51623213,
        "_source": {
          "id": 1,
          "name": "張三",
          "age": 18,
          "createtime": "2020-09-01 16:16:16",
          "productID": "XHDK-A-1293-#fJ3"
        }
      }
    ]
  }
}
  • 如果覺得短語匹配過於嚴格,那麼也可以設定slop這個關鍵字指定相隔的距離。

舉例:

先新增一個名字為張啊三的資料

PUT /my_index/my_type/_bulk
{ "index": { "_id":4}}
{ "id":4,"name": "張啊三","age":26,"createtime":"2020-10-01 16:16:16","productID":"XHDK-B-1293-#fJ2"}
{ "index": { "_id":5}}
{ "id":5,"name": "張家口測試三","age":26,"createtime":"2020-10-01 16:16:16","productID":"XHDK-B-1293-#fJ2"}

查詢:
GET /my_index/my_type/_search
{
  "query": {
    "match_phrase": {
      "name":{
        "query": "張三",
        "slop":1          設定分詞相隔距離
      }
    }
  }
}

查詢結果:
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.51623213,
    "hits": [
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "1",
        "_score": 0.51623213,
        "_source": {
          "id": 1,
          "name": "張三",
          "age": 18,
          "createtime": "2020-09-01 16:16:16",
          "productID": "XHDK-A-1293-#fJ3"
        }
      },
      {
        "_index": "my_index",
        "_type": "my_type",
        "_id": "4",
        "_score": 0.42991763,
        "_source": {
          "id": 4,
          "name": "張啊三",
          "age": 26,
          "createtime": "2020-10-01 16:16:16",
          "productID": "XHDK-B-1293-#fJ2"
        }
      }
    ]
  }
}

排序

  • 使用sort可以進行排序
GET /my_index/my_type/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "createtime": {
        "order": "desc"
      },
      "age": {
        "order": "desc"
      }
    }
  ]
}

-- 對於文字排序就比較特殊,不能在analyzed(分析過)的字串欄位上排序,因為分析器將字串拆分成了很多詞彙單元,就像一個 詞彙袋 ,所以 Elasticsearch 不知道使用那一個詞彙單元排序。所以analyzed 域用來搜尋, not_analyzed 域用來排序。但是依賴於 not_analyzed 域來排序的話不是很靈活,也可以[自定義分析器](https://www.elastic.co/guide/cn/elasticsearch/guide/current/sorting-collations.html)進行排序。

GET /my_index/my_type/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "productID.keyword": {
        "order": "desc"
      }
    }
  ]
} 

range(範圍查詢)

  • gt : > 大於(greater than)
  • lt : < 小於(less than)
  • gte : >= 大於或等於(greater than or equal to)
  • lte : <= 小於或等於(less than or equal to)
GET /my_index/my_type/_search
{
  "query": {
    "range": {
      "createtime": {
        "lte": "now"    小於等於當前時間
      }
    }
  }
}

GET /my_index/my_type/_search
{
  "query": {
    "range": {
      "createtime": {
        "lte": "now-1M"  小於等於當前時間減去一個月    
      }
    }
  }
}

y:年、M:月、d:天、h:時、m:分、s:秒

GET /my_index/my_type/_search
{
  "query": {
    "range": {
      "createtime": {
        "gte": "2020-10-01 16:16:16",   也可以指定到秒
        "lte": "2020-10-01 16:16:16"
      }
    }
  }
}

GET /my_index/my_type/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 18,    數值型別
        "lte": 20
      }
    }
  }
}

fuzzy(模糊查詢)

  • fuzzy 查詢是一個詞項級別的查詢,所以它不做任何分析。它通過某個詞項以及指定的 fuzziness 查詢到詞典中所有的詞項。 fuzziness 預設設定為 AUTO 。
  • Elasticsearch 指定了 fuzziness引數支援對最大編輯距離的配置,預設為2。建議設定為1會得到更好的結果和更好的效能。
GET /my_index/my_type/_search
{
  "query": {
    "fuzzy": {
      "productID": {
        "value": "xhdl",   你如果輸入的是XHDL是查詢不到的,因為查詢語句並沒有被分詞器分析。
        "fuzziness": 1
      }
    }
  }
}

null值的查詢

  • exists這個語句用來查詢存在值的資訊,如果和must結合表示查詢不為null的資料,如果must_not集合表示查詢為null的資料,如下
先新增一條訂單號為null的資料:

PUT /my_index/my_type/_bulk
{ "index": { "_id":6}}
{ "id":6,"name": "趙六","age":22,"createtime":"2020-10-01 16:16:16"}

查詢productID為null的資料:

GET my_index/my_type/_search
{
  "query": {
    "bool": {
      "must_not":{
        "exists":{
          "field":"productID"
        }
      }
    }
  }
}

查詢productID不為null的資料:

GET my_index/my_type/_search
{
  "query": {
    "bool": {
      "must":{
        "exists":{
          "field":"productID"
        }
      }
    }
  }
}

filter(過濾查詢)

  • 快取,不返回相關性,速度比query快

簡單的過濾器

  • 使用post_filter
GET /my_index/my_type/_search
{
  "post_filter": {
    "term": {
      "age": 20
    }
  }
}

使用bool組合過濾器

  • must :所有的語句都 必須(must) 匹配,與 AND 等價。
  • must_not :所有的語句都 不能(must not) 匹配,與 NOT 等價。
  • should:至少有一個語句要匹配,與 OR 等價。
GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "must_not": [
        {}
      ],
      "must": [
        {}
      ],
      "should": [
        {}
      ]
    }
  }
}

-- 根據業務需求選擇。

例項:匹配查詢張三,並且年齡是18歲的。

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "張三"
          }
        },
        {
          "term": {
            "age": {
              "value": 18
            }
          }
        }
      ]
    }
  }
}

匹配查詢叫張三,年齡在20到30之間並且訂單號中不包含kdke的資料。

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "張三"
          }
        },
        {
          "range": {
            "age": {
              "gte": 20,
              "lte": 30
            }
          }
        }
      ],
      "must_not": [
        {
          "term": {
            "productID": "kdke"
          }
        }
      ]
    }
  }
}

巢狀bool組合過濾查詢

GET /my_index/my_type/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "張三"
          }
        },
        {
          "range": {
            "age": {
              "gte": 20,
              "lte": 30
            }
          }
        },
        {
          "bool": {
            "should": [
              {
                "match_phrase":{
                  "name": "測試"
                }
              }
            ]
          }
        }
      ]
     }
    }
 
} 

聚合查詢

  • 在sql中有許多的聚合函式,那麼在Elasticsearch中頁存在這些聚合函式,比如sum,avg,count等等

count:數量

GET my_index/my_type/_search
{
  "size": 0,    在使用聚合時,預設返回10條資料,可以設定大小,如果不需要可以設定為0
  "aggs": {
    "count_age": {    //自定義返回的欄位名稱
      "value_count": {  //count是查詢聚合函式的數量
        "field": "age"    //指定的聚合欄位
      }
    }
  }
}

avg: 平均值

GET my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "avg_age": {
      "avg": {
        "field": "age"
      }
    }
  }
}

max: 最大值

GET my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "max_age": {
      "max": {
        "field": "age"
      }
    }
  }
}

min: 最小值

GET my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "min_age": {
      "min": {
        "field": "age"
      }
    }
  }
}

sum: 求和

GET my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "sum_age": {
      "sum": {
        "field": "age"
      }
    }
  }
}

stats: 統計聚合,基於文件的某個值,計算出一些統計資訊(min、max、sum、count、avg)。

GET my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "stats_age": {
      "stats": {
        "field": "age"
      }
    }
  }
}

cardinality:相當於該欄位互不相同的值有多少類,輸出的是種類數

GET my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "cardinality_age": {
      "cardinality": {
        "field": "age"
      }
    }
  }
}

group(分組),使用的是terms

新增資料:

PUT /my_index/my_type/_bulk
{ "index": { "_id":7}}
{ "id":7,"name": "鮮橙多","age":15,"createtime":"2020-07-01 16:16:16","productID":"XHDK-C-1293-#fJ3"}
{ "index": { "_id":8}}
{ "id":8,"name": "果粒橙","age":20,"createtime":"2020-12-01 16:16:16","productID":"KDKH-B-9947-#kL5"}
{ "index": { "_id": 9}}
{"id":9, "name": "可口可樂","age":25,"createtime":"2020-09-02 16:16:16","productID":"JODL-X-1937-#pV7"}
{ "index": { "_id":10}}
{ "id":10,"name": "紅牛","age":18,"createtime":"2020-09-10 16:16:16","productID":"XHDF-A-1293-#fJ3"}
{ "index": { "_id":11}}
{ "id":11,"name": "體制能量","age":20,"createtime":"2020-08-01 16:16:16","productID":"KDKE-B-9947-#kL5"}
{ "index": { "_id": 12}}
{"id":12, "name": "芬達","age":22,"createtime":"2020-09-02 16:16:16","productID":"JODL-X-1937-#pV7"}


GET my_index/my_type/_search
{
  "size": 0,         返回條數,預設返回10條。
  "aggs": {
    "age_group": {    自定義返回的聚合桶名稱
      "terms": {
        "field": "age",      分組欄位
        "size":10           返回分組的數量,預設返回10條
      }
    }
  }
}


查詢結果:
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 12,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "age_group": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": 20,          每個桶key
          "doc_count": 3      每個桶的文件數量。
        },
        {
          "key": 22,
          "doc_count": 3
        },
        {
          "key": 18,
          "doc_count": 2
        },
        {
          "key": 26,
          "doc_count": 2
        },
        {
          "key": 15,
          "doc_count": 1
        },
        {
          "key": 25,
          "doc_count": 1
        }
      ]
    }
  }
}
  • 查詢年齡18到22隨的使用者並且按建立時間分組
GET /my_index/my_type/_search
{
  "size": 0, 
  "query": {
    "range": {
      "age": {
        "gte": 18,
        "lte": 22
      }
    }
  },
  "aggs": {
    "group_createtime": {
      "terms": {
        "field": "createtime.keyword",
        "size": 10
      }
    }
  }
}

查詢結果:

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_createtime": {        
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "2020-08-01 16:16:16",  
          "doc_count": 2
        },
        {
          "key": "2020-09-02 16:16:16",
          "doc_count": 2
        },
        {
          "key": "2020-09-01 16:16:16",
          "doc_count": 1
        },
        {
          "key": "2020-09-10 16:16:16",
          "doc_count": 1
        },
        {
          "key": "2020-10-01 16:16:16",
          "doc_count": 1
        },
        {
          "key": "2020-12-01 16:16:16",
          "doc_count": 1
        }
      ]
    }
  }
}
  • 針對年齡在18到22歲之間的使用者按照建立時間分組,並按照分組結果進行正序
GET /my_index/my_type/_search
{
  "size": 0, 
  "query": {
    "range": {
      "age": {
        "gte": 18,
        "lte": 22
      }
    }
  },
  "aggs": {
    "group_createtime": {
      "terms": {
        "field": "createtime.keyword",
        "size": 10,
        "order": {
          "_term": "asc"
        }
      }
    }
  }
}
  • 針對年齡在18到22歲之間的使用者並按建立時間分組後再按年齡分組結果倒序排,求出年齡平均值
GET /my_index/my_type/_search
{
  "size": 0, 
  "query": {
    "range": {
      "age": {
        "gte": 18,
        "lte": 22
      }
    }
  },
  "aggs": {
    "group_createtime": {
      "terms": {
        "field": "createtime.keyword",
        "size": 10
      },
      "aggs": {
        "group_age": {
          "terms": {
            "field": "age",
            "size": 10,
            "order": {
              "_term": "desc"
            }
          }
        }
      }
    },
    "avg_age":{
      "avg": {
        "field": "age"
      }
    }
  }
}
  • 針對年齡在18到22歲之間的使用者並按建立時間分組後再按照年齡分組,時間分組後再按照每個時間段年齡數量倒序排,求出年齡平均值。
GET /my_index/my_type/_search
{
  "size": 0, 
  "query": {
    "range": {
      "age": {
        "gte": 18,
        "lte": 22
      }
    }
  },
  "aggs": {
    "group_createtime": {
      "terms": {
        "field": "createtime.keyword",
        "size": 10,
        "order": {
          "terms_age.count": "desc"
        }
      },
      "aggs": {
        "terms_age": {
          "extended_stats": {    度量計算,可以按照度量排序
            "field": "age"
          }
        },
        "group_age": {
          "terms": {
            "field": "age",
            "size": 10
          }
        }
      }
    },
    "avg_age":{
      "avg": {
        "field": "age"
      }
    }
  }
}

  • 聚合去重

查詢使用者訂單號的數量

GET /my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "cardinality_productID": {
      "cardinality": {
        "field": "productID.keyword"
      }
    }
  }
}

結果:
{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 12,       總數量12個
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "cardinality_productID": {
      "value": 7            說明有7種訂單號
    }
  }
}

date_histogram(按時間聚合統計)

  • 查詢出每月份時間段訂單完成數量最多
GET /my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "date_month": {
      "date_histogram": {
        "field": "createtime",
        "interval": "month"
      },
      "aggs": {
        "cardinality_productID": {
          "cardinality": {
            "field": "productID.keyword"
          }
        }
      }
    }
  }
}

結果:
{
  "took": 12,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 12,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "date_month": {
      "buckets": [
        {
          "key_as_string": "2020-07-01 00:00:00",
          "key": 1593561600000,
          "doc_count": 1,
          "cardinality_productID": {
            "value": 1
          }
        },
        {
          "key_as_string": "2020-08-01 00:00:00",
          "key": 1596240000000,
          "doc_count": 2,
          "cardinality_productID": {
            "value": 1
          }
        },
        {
          "key_as_string": "2020-09-01 00:00:00",
          "key": 1598918400000,
          "doc_count": 5,
          "cardinality_productID": {
            "value": 3
          }
        },
        {
          "key_as_string": "2020-10-01 00:00:00",
          "key": 1601510400000,
          "doc_count": 3,
          "cardinality_productID": {
            "value": 1
          }
        },
        {
          "key_as_string": "2020-11-01 00:00:00",
          "key": 1604188800000,
          "doc_count": 0,
          "cardinality_productID": {
            "value": 0
          }
        },
        {
          "key_as_string": "2020-12-01 00:00:00",
          "key": 1606780800000,
          "doc_count": 1,
          "cardinality_productID": {
            "value": 1
          }
        }
      ]
    }
  }
}
  • 但是我們想要檢視2020年每月份所有訂單數量,沒有訂單的月份返回0
GET /my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "date_month": {
      "date_histogram": {
        "field": "createtime",
        "interval": "month",
        "format":"yyyy-MM",   日期格式化
        "min_doc_count": 0,    強制返回空桶,預設會被過濾掉
        "extended_bounds":{   設定需要聚合的時間段,預設返回全部
          "min":"2020-01",   
          "max":"2020-12"
        }
      },
      "aggs": {
        "cardinality_productID": {
          "cardinality": {
            "field": "productID.keyword"
          }
        }
      }
    }
  }
}
  • 我們想獲取2020所有月份完成訂單數量以及使用者姓名,按照訂單數量倒序排
GET /my_index/my_type/_search
{
  "size": 0, 
  "aggs": {
    "date_month": {
      "date_histogram": {
        "field": "createtime",
        "interval": "month",
        "format":"yyyy-MM",
        "min_doc_count": 0,
        "extended_bounds":{
          "min":"2020-01",
          "max":"2020-12"
        },
        "order": {
          "cardinality_productID": "desc"
        }
      },
      "aggs": {
        "cardinality_productID": {
          "cardinality": {
            "field": "productID.keyword"
          }
        }
      }
    }
  }
}