es使用與原理5 -- 中文分詞及熱更新詞庫,聚合分析等等

中國人很喜歡吃油條的中英文分詞器兩種分法

standard:中 國 人 很 喜 歡 吃 油 條
ik:中國人 很 喜歡 吃 油條

1、在elasticsearch中安裝ik中文分詞器

(1)git clone https://github.com/medcl/elasticsearch-analysis-ik
(2)git checkout tags/v5.2.0
(3)mvn package
(4)將target/releases/elasticsearch-analysis-ik-5.2.0.zip拷貝到es/plugins/ik目錄下
(5)在es/plugins/ik下對elasticsearch-analysis-ik-5.2.0.zip進行解壓縮
(6)重啟es
2、ik分詞器的兩種分詞策略(一般使用 ik_max_word策略)
ik_max_word: 會將文本做最細粒度的拆分,比如會將“中華人民共和國國歌”拆分為“中華人民共和國,中華人民,中華,華人,人民共和國,人民,人,民,共和國,共和,和,國國,國歌”,會窮盡各種可能的組合;

ik_smart: 會做最粗粒度的拆分,比如會將“中華人民共和國國歌”拆分為“中華人民共和國,國歌”。


PUT /my_index 
{
  "mappings": {
    "my_type": {
      "properties": {
        "text": {
          "type": "text",
          "analyzer": "ik_max_word"
        }
      }
    }
  }
}

POST /my_index/my_type/_bulk
{ "index": { "_id": "1"} }
{ "text": "男子偷上萬元發(fā)紅包求交女友 被抓獲時仍然單身" }
{ "index": { "_id": "2"} }
{ "text": "16歲少女為結婚“變”22歲 7年后想離婚被法院拒絕" }
{ "index": { "_id": "3"} }
{ "text": "深圳女孩騎車逆行撞奔馳 遭索賠被嚇哭(圖)" }
{ "index": { "_id": "4"} }
{ "text": "女人對護膚品比對男票好?網(wǎng)友神懟" }
{ "index": { "_id": "5"} }
{ "text": "為什么國內的街道招牌用的都是紅黃配?" }

GET /my_index/_analyze
{
  "text": "男子偷上萬元發(fā)紅包求交女友 被抓獲時仍然單身",
  "analyzer": "ik_max_word"
}

GET /my_index/my_type/_search 
{
  "query": {
    "match": {
      "text": "16歲少女結婚好還是單身好?"
    }
  }
}
IK分詞器配置文件及自定義詞庫

1、ik配置文件

ik配置文件地址:es/plugins/ik/config目錄

IKAnalyzer.cfg.xml:用來配置自定義詞庫
main.dic:ik原生內置的中文詞庫,總共有27萬多條,只要是這些單詞,都會被分在一起
quantifier.dic:放了一些單位相關的詞
suffix.dic:放了一些后綴
surname.dic:中國的姓氏
stopword.dic:英文停用詞

ik原生最重要的兩個配置文件

main.dic:包含了原生的中文詞語,會按照這個里面的詞語去分詞
stopword.dic:包含了英文的停用詞
停用詞,stopword

a the and at but ,一般,像停用詞,會在分詞的時候,直接被干掉,不會建立在倒排索引中
2、自定義詞庫

(1)自己建立詞庫:每年都會涌現(xiàn)一些特殊的流行詞,網(wǎng)紅,藍瘦香菇,喊麥,鬼畜,一般不會在ik的原生詞典里

自己補充自己的最新的詞語,到ik的詞庫里面去

IKAnalyzer.cfg.xml:ext_dict,custom/mydict.dic

補充自己的詞語,然后需要重啟es,才能生效

(2)自己建立停用詞庫:比如了,的,啥,么,我們可能并不想去建立索引,讓人家搜索

custom/ext_stopword.dic,已經有了常用的中文停用詞,可以補充自己的停用詞,然后重啟es

修改IK分詞器源碼來基于mysql熱更新詞庫

每次都是在es的擴展詞典中,手動添加新詞語,很坑
(1)每次添加完,都要重啟es才能生效,非常麻煩
(2)es是分布式的,可能有數(shù)百個節(jié)點,你不能每次都一個一個節(jié)點上面去修改

es不停機,直接我們在外部某個地方添加新的詞語,es中立即熱加載到這些新詞語

兩種熱更新的方案
(1)修改ik分詞器源碼,然后手動支持從mysql中每隔一定時間,自動加載新的詞庫
(2)基于ik分詞器原生支持的熱更新方案,部署一個web服務器,提供一個http接口,通過modified和tag兩個http響應頭,來提供詞語的熱更新

一般都用第一種方案,第二種 ik git社區(qū)官方都不建議采用,覺得不太穩(wěn)定

2、修改源碼

Dictionary類,169行:Dictionary單例類的初始化方法,在這里需要創(chuàng)建一個我們自定義的線程,并且啟動它 new Thread(new HotDictReloadThread()).start();
HotDictReloadThread類:就是死循環(huán),不斷調用Dictionary.getSingleton().reLoadMainDict(),去重新加載詞典 loadMainDict
Dictionary類,389行:this.loadMySQLExtDict();
Dictionary類,683行:this.loadMySQLStopwordDict();

3、mvn package打包代碼

target\releases\elasticsearch-analysis-ik-5.2.0.zip

4、解壓縮ik壓縮包

將mysql驅動jar,放入ik的目錄下

5、修改jdbc相關配置

6、重啟es

觀察日志,日志中就會顯示我們打印的那些東西,比如加載了什么配置,加載了什么詞語,什么停用詞

7、在mysql中添加詞庫與停用詞

8、分詞實驗,驗證熱更新生效

聚合分析之bucket和metric

bucket:按照某個字段進行bucket劃分,那個字段的值相同的那些數(shù)據(jù),就會被劃分到一個bucket中。如:
北京 小李
北京 小王
上海 小張
上海 小麗
上海 小陳
基于city劃分buckets 劃分出來兩個bucket,一個是北京bucket,一個是上海bucket
北京bucket:包含了2個人,小李,小王
上海bucket:包含了3個人,小張,小麗,小陳
metric:對一個數(shù)據(jù)分組執(zhí)行的統(tǒng)計。當我們有了一堆bucket之后,就可以對每個bucket中的數(shù)據(jù)進行聚合分詞了,比如說計算一個bucket內所有數(shù)據(jù)的數(shù)量,或者計算一個bucket內所有數(shù)據(jù)的平均值,最大值,最小值
聚合統(tǒng)計--哪種顏色電視銷量最高

PUT /tvs
{
    "mappings": {
        "sales": {
            "properties": {
                "price": {
                    "type": "long"
                },
                "color": {
                    "type": "keyword"
                },
                "brand": {
                    "type": "keyword"
                },
                "sold_date": {
                    "type": "date"
                }
            }
        }
    }
}

POST /tvs/sales/_bulk
{ "index": {}}
{ "price" : 1000, "color" : "紅色", "brand" : "長虹", "sold_date" : "2016-10-28" }
{ "index": {}}
{ "price" : 2000, "color" : "紅色", "brand" : "長虹", "sold_date" : "2016-11-05" }
{ "index": {}}
{ "price" : 3000, "color" : "綠色", "brand" : "小米", "sold_date" : "2016-05-18" }
{ "index": {}}
{ "price" : 1500, "color" : "藍色", "brand" : "TCL", "sold_date" : "2016-07-02" }
{ "index": {}}
{ "price" : 1200, "color" : "綠色", "brand" : "TCL", "sold_date" : "2016-08-19" }
{ "index": {}}
{ "price" : 2000, "color" : "紅色", "brand" : "長虹", "sold_date" : "2016-11-05" }
{ "index": {}}
{ "price" : 8000, "color" : "紅色", "brand" : "三星", "sold_date" : "2017-01-01" }
{ "index": {}}
{ "price" : 2500, "color" : "藍色", "brand" : "小米", "sold_date" : "2017-02-12" }

2、統(tǒng)計哪種顏色的電視銷量最高

GET /tvs/sales/_search
{
    "size" : 0,
    "aggs" : { 
        "popular_colors" : { 
            "terms" : { 
              "field" : "color"
            }
        }
    }
}

# 請求參數(shù)解釋
size:只獲取聚合結果,而不要執(zhí)行聚合的原始數(shù)據(jù)
aggs:固定語法,要對一份數(shù)據(jù)執(zhí)行分組聚合操作
popular_colors:就是對每個aggs,都要起一個名字,這個名字是隨機的,你隨便取什么都ok
terms:根據(jù)字段的值進行分組
field:根據(jù)指定的字段的值進行分組

//返回結果
{
  "took": 22,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "popular_colors": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "紅色",
          "doc_count": 4
        },
        {
          "key": "綠色",
          "doc_count": 2
        },
        {
          "key": "藍色",
          "doc_count": 2
        }
      ]
    }
  }
}
# 返回數(shù)據(jù)解釋:
hits.hits:我們指定了size是0,所以hits.hits就是空的,否則會把執(zhí)行聚合的那些原始數(shù)據(jù)給你返回回來
aggregations:聚合結果
popular_color:我們指定的某個聚合的名稱
buckets:根據(jù)我們指定的field劃分出的buckets
key:每個bucket對應的那個值
doc_count:這個bucket分組內,有多少個數(shù)據(jù)
數(shù)量,其實就是這種顏色的銷量

默認的排序規(guī)則:按照doc_count降序排序

聚合統(tǒng)計--bucket+metric:統(tǒng)計每種顏色電視平均價格
在之前的terms同級下,新增一個aggs分組之后,聚合求平均

GET /tvs/sales/_search
{
   "size" : 0,
   "aggs": {
      "colors": {
         "terms": {
            "field": "color"
         },
         "aggs": { 
            "avg_price": { 
               "avg": {
                  "field": "price" 
               }
            }
         }
      }
   }
}

# 返回數(shù)據(jù)
{
  "took": 14,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "colors": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "紅色",
          "doc_count": 4,
          "avg_price": {
            "value": 3250
          }
        },
        {
          "key": "綠色",
          "doc_count": 2,
          "avg_price": {
            "value": 2100
          }
        },
        {
          "key": "藍色",
          "doc_count": 2,
          "avg_price": {
            "value": 2000
          }
        }
      ]
    }
  }
}
# 返回數(shù)據(jù)解釋
buckets,除了key和doc_count
avg_price:我們自己取的metric aggs的名字
value:我們的metric計算的結果,每個bucket中的數(shù)據(jù)的price字段求平均值后的結果

select avg(price) from tvs.sales group by color

bucket嵌套實現(xiàn)顏色+品牌的多層下鉆分析
比如說,現(xiàn)在紅色的電視有4臺,同時這4臺電視中,有3臺是屬于長虹的,1臺是屬于小米的
紅色電視中的3臺長虹的平均價格是多少?
紅色電視中的1臺小米的平均價格是多少?

下鉆的意思是,已經分了一個組了,比如說顏色的分組,然后還要繼續(xù)對這個分組內的數(shù)據(jù),再分組,比如一個顏色內,還可以分成多個不同的品牌的組,最后對每個最小粒度的分組執(zhí)行聚合分析操作,這就叫做下鉆分析

GET /tvs/sales/_search
{
  "size": 0,
  "aggs": { 
      "顏色分組":{
        "terms": {
          "field": "color" 
        },
        "aggs": {
          "顏色求平均": {
            "avg": {
              "field": "price"
            }
          },
          "品牌分組":{
            "terms": {
              "field": "brand"
            },
            "aggs": {
              "品牌求平均": {
                "avg": {
                  "field": "price"
                }
              }
            }
          }
        }
      }
  }
}

//返回數(shù)據(jù)
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "顏色分組": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "紅色",
          "doc_count": 4,
          "品牌分組": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "長虹",
                "doc_count": 3,
                "品牌求平均": {
                  "value": 1666.6666666666667
                }
              },
              {
                "key": "三星",
                "doc_count": 1,
                "品牌求平均": {
                  "value": 8000
                }
              }
            ]
          },
          "顏色求平均": {
            "value": 3250
          }
        },
        {
          "key": "綠色",
          "doc_count": 2,
          "品牌分組": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "TCL",
                "doc_count": 1,
                "品牌求平均": {
                  "value": 1200
                }
              },
              {
                "key": "小米",
                "doc_count": 1,
                "品牌求平均": {
                  "value": 3000
                }
              }
            ]
          },
          "顏色求平均": {
            "value": 2100
          }
        },
        {
          "key": "藍色",
          "doc_count": 2,
          "品牌分組": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "TCL",
                "doc_count": 1,
                "品牌求平均": {
                  "value": 1500
                }
              },
              {
                "key": "小米",
                "doc_count": 1,
                "品牌求平均": {
                  "value": 2500
                }
              }
            ]
          },
          "顏色求平均": {
            "value": 2000
          }
        }
      ]
    }
  }
}

metrics:統(tǒng)計每種顏色電視最大最小價格
之前我們也可以求數(shù)量和平均值
count:bucket,terms,自動就會有一個doc_count,就相當于是count
avg:avg aggs,求平均值

現(xiàn)在我們使用更多的metrics操作
max:求一個bucket內,指定field值最大的那個數(shù)據(jù)
min:求一個bucket內,指定field值最小的那個數(shù)據(jù)
sum:求一個bucket內,指定field值的總和
一般來說,90%的常見的數(shù)據(jù)分析的操作,metric,無非就是count,avg,max,min,sum

GET /tvs/sales/_search
{
   "size" : 0,
   "aggs": {
      "colors": {
         "terms": {
            "field": "color"
         },
         "aggs": {
            "avg_price": { "avg": { "field": "price" } },
            "min_price" : { "min": { "field": "price"} }, 
            "max_price" : { "max": { "field": "price"} },
            "sum_price" : { "sum": { "field": "price" } } 
         }
      }
   }
}

//返回數(shù)據(jù)
{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "colors": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "紅色",
          "doc_count": 4,
          "max_price": {
            "value": 8000
          },
          "min_price": {
            "value": 1000
          },
          "avg_price": {
            "value": 3250
          },
          "sum_price": {
            "value": 13000
          }
        },
        {
          "key": "綠色",
          "doc_count": 2,
          "max_price": {
            "value": 3000
          },
          "min_price": {
            "value": 1200
          },
          "avg_price": {
            "value": 2100
          },
          "sum_price": {
            "value": 4200
          }
        },
        {
          "key": "藍色",
          "doc_count": 2,
          "max_price": {
            "value": 2500
          },
          "min_price": {
            "value": 1500
          },
          "avg_price": {
            "value": 2000
          },
          "sum_price": {
            "value": 4000
          }
        }
      ]
    }
  }
}

hitogram按價格區(qū)間統(tǒng)計電視銷量和銷售額
histogram:類似于terms,也是進行bucket分組操作,接收一個field,按照這個field的值的各個范圍區(qū)間,進行bucket分組操作
interval:2000,劃分范圍,02000,20004000,40006000,60008000,8000~10000,buckets
去根據(jù)price的值,比如2500,看落在哪個區(qū)間內,比如20004000,此時就會將這條數(shù)據(jù)放入20004000對應的那個bucket中
bucket劃分的方法,terms,將field值相同的數(shù)據(jù)劃分到一個bucket中
bucket有了之后,一樣的,去對每個bucket執(zhí)行avg,count,sum,max,min,等各種metric操作,聚合分析

以2000位區(qū)間段,求各個區(qū)間的產品價格總和

GET /tvs/sales/_search
{
   "size" : 0,
   "aggs":{
      "price":{
         "histogram":{ 
            "field": "price",
            "interval": 2000
         },
         "aggs":{
            "revenue": {
               "sum": { 
                 "field" : "price"
               }
             }
         }
      }
   }
}

//返回數(shù)據(jù)
{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "price": {
      "buckets": [
        {
          "key": 0,
          "doc_count": 3,
          "revenue": {
            "value": 3700
          }
        },
        {
          "key": 2000,
          "doc_count": 4,
          "revenue": {
            "value": 9500
          }
        },
        {
          "key": 4000,
          "doc_count": 0,
          "revenue": {
            "value": 0
          }
        },
        {
          "key": 6000,
          "doc_count": 0,
          "revenue": {
            "value": 0
          }
        },
        {
          "key": 8000,
          "doc_count": 1,
          "revenue": {
            "value": 8000
          }
        }
      ]
    }
  }
}

日期間隔舉例

GET /tvs/sales/_search
{
   "size" : 0,
   "aggs": {
      "sales": {
         "date_histogram": {
            "field": "sold_date",
            "interval": "month", 
            "format": "yyyy-MM-dd",
            "min_doc_count" : 0, 
            "extended_bounds" : { 
                "min" : "2016-01-01",
                "max" : "2017-12-31"
            }
         }
      }
   }
}
# 參數(shù)解釋
min_doc_count:即使某個日期interval,2017-01-01~2017-01-31中,一條數(shù)據(jù)都沒有,那么這個區(qū)間也是要返回的,不然默認是會過濾掉這個區(qū)間的
extended_bounds,min,max:劃分bucket的時候,會限定在這個起始日期,和截止日期內

//返回數(shù)據(jù)
{
  "took": 10,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "sales": {
      "buckets": [
        {
          "key_as_string": "2016-01-01",
          "key": 1451606400000,
          "doc_count": 0
        },
        {
          "key_as_string": "2016-02-01",
          "key": 1454284800000,
          "doc_count": 0
        },
        {
          "key_as_string": "2016-03-01",
          "key": 1456790400000,
          "doc_count": 0
        },
        {
          "key_as_string": "2016-04-01",
          "key": 1459468800000,
          "doc_count": 0
        },
        {
          "key_as_string": "2016-05-01",
          "key": 1462060800000,
          "doc_count": 1
        },
        {
          "key_as_string": "2016-06-01",
          "key": 1464739200000,
          "doc_count": 0
        },
        {
          "key_as_string": "2016-07-01",
          "key": 1467331200000,
          "doc_count": 1
        },
        {
          "key_as_string": "2016-08-01",
          "key": 1470009600000,
          "doc_count": 1
        },
        {
          "key_as_string": "2016-09-01",
          "key": 1472688000000,
          "doc_count": 0
        },
        {
          "key_as_string": "2016-10-01",
          "key": 1475280000000,
          "doc_count": 1
        },
        {
          "key_as_string": "2016-11-01",
          "key": 1477958400000,
          "doc_count": 2
        },
        {
          "key_as_string": "2016-12-01",
          "key": 1480550400000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-01-01",
          "key": 1483228800000,
          "doc_count": 1
        },
        {
          "key_as_string": "2017-02-01",
          "key": 1485907200000,
          "doc_count": 1
        },
        {
          "key_as_string": "2017-03-01",
          "key": 1488326400000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-04-01",
          "key": 1491004800000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-05-01",
          "key": 1493596800000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-06-01",
          "key": 1496275200000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-07-01",
          "key": 1498867200000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-08-01",
          "key": 1501545600000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-09-01",
          "key": 1504224000000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-10-01",
          "key": 1506816000000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-11-01",
          "key": 1509494400000,
          "doc_count": 0
        },
        {
          "key_as_string": "2017-12-01",
          "key": 1512086400000,
          "doc_count": 0
        }
      ]
    }
  }
}
下鉆分析之統(tǒng)計每季度每個品牌的銷售額

其實就是先分組再下鉆聚合

GET /tvs/sales/_search 
{
  "size": 0,
  "aggs": {
    "group_by_sold_date": {
      "date_histogram": {
        "field": "sold_date",
        "interval": "quarter",//quarter是季度的意思,這里是按照季度去劃分
        "format": "yyyy-MM-dd",
        "min_doc_count": 0,
        "extended_bounds": {
          "min": "2016-01-01",
          "max": "2017-12-31"
        }
      },
      "aggs": {
        "group_by_brand": { //按照品牌下鉆分析
          "terms": {
            "field": "brand"
          },
          "aggs": {
            "sum_price": {
              "sum": {
                "field": "price"
              }
            }
          }
        },
        "total_sum_price": {//每個季度的總銷售額
          "sum": {
            "field": "price"
          }
        }
      }
    }
  }
}

搜索+聚合:統(tǒng)計指定品牌下每個顏色的銷量
其實就是搜索和聚合操作相結合

GET /tvs/sales/_search 
{
  "size": 0,
  "query": {
    "term": {
      "brand": {
        "value": "小米"
      }
    }
  },
  "aggs": {
    "group_by_color": {
      "terms": {
        "field": "color"
      }
    }
  }
}

global bucket:單個品牌與所有品牌銷量對比
global:就是global bucket,就是將所有數(shù)據(jù)納入聚合的scope,而不管之前的query。
出來兩個結果,一個結果,是基于query搜索結果來聚合的; 一個結果,是對所有數(shù)據(jù)執(zhí)行聚合的

GET /tvs/sales/_search 
{
  "size": 0, 
  "query": {
    "term": {
      "brand": {
        "value": "長虹"
      }
    }
  },
  "aggs": {
    "single_brand_avg_price": {
      "avg": {
        "field": "price"
      }
    },
    "all": {
      "global": {},
      "aggs": {
        "all_brand_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

//返回結果
{
  "took": 12,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "all": {
      "doc_count": 8,
      "all_brand_avg_price": {
        "value": 2650
      }
    },
    "single_brand_avg_price": {
      "value": 1666.6666666666667
    }
  }
}

過濾+聚合:統(tǒng)計價格大于1200的電視平均價格
先過濾再聚合

GET /tvs/sales/_search 
{
  "size": 0,
  "query": {
    "constant_score": {
      "filter": {
        "range": {
          "price": {
            "gte": 1200
          }
        }
      }
    }
  },
  "aggs": {
    "avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

bucket filter:一次統(tǒng)計牌品最近N,M天的平均價格

GET /tvs/sales/_search 
{
  "size": 0,
  "query": {
    "term": {
      "brand": {
        "value": "長虹"
      }
    }
  },
  "aggs": {
    "recent_150d": {
      "filter": {
        "range": {
          "sold_date": {
            "gte": "now-150d"
          }
        }
      },
      "aggs": {
        "recent_150d_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "recent_140d": {
      "filter": {
        "range": {
          "sold_date": {
            "gte": "now-140d"
          }
        }
      },
      "aggs": {
        "recent_140d_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    },
    "recent_130d": {
      "filter": {
        "range": {
          "sold_date": {
            "gte": "now-130d"
          }
        }
      },
      "aggs": {
        "recent_130d_avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

aggs.filter,針對的是聚合去做的

如果放query里面的filter,是全局的,會對所有的數(shù)據(jù)都有影響

但是,如果,比如說,你要統(tǒng)計,長虹電視,最近1個月的平均值; 最近3個月的平均值; 最近6個月的平均值
我們就可以使用bucket filter:對不同的bucket下的aggs,進行filter
排序:按每種顏色的平均銷售額降序排序
之前的話,排序,是按照每個bucket的doc_count降序來排的,但是假如說,我們現(xiàn)在統(tǒng)計出來每個顏色的電視的銷售額,需要按照銷售額降序排序????

GET /tvs/sales/_search 
{
  "size": 0,
  "aggs": {
    "group_by_color": {
      "terms": {
        "field": "color",
        "order": {
          "avg_price": "asc"http://根據(jù) avg_price來升序排序
        }
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

顏色+品牌下鉆分析時按最深層metric進行排序

GET /tvs/sales/_search 
{
  "size": 0,
  "aggs": {
    "group_by_color": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "group_by_brand": {
          "terms": {
            "field": "brand",
            "order": {
              "avg_price": "desc"http://這里是最深層 在這里做排序就好了
            }
          },
          "aggs": {
            "avg_price": {
              "avg": {
                "field": "price"
              }
            }
          }
        }
      }
    }
  }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容