在本文中,我們將重點關注significant terms和significant text聚合。這些聚合旨在搜索數據集中有趣和/或不尋常的術語,這些術語可以告訴您有關數據的隱藏屬性的更多信息。此功能對於以下用例特別有用:
- 為用戶查詢標識包含同義詞,首字母縮略詞等的相關文檔。例如,當用戶搜索H1N1時,重要術語聚合可能會建議帶有“bird flu”的文檔。
- 識別數據中的異常和有趣的事件。例如,通過基於位置過濾文檔,我們可以確定特定區域中最常見的犯罪類型。
- 使用對整數字段(例如身高,體重,收入等)的significant term聚合來確定一組主題的最重要屬性。
應當注意,重要術語和重要文本聚合都對直接查詢(前景集)和索引中所有其他文檔(背景集)檢索的文檔執行復雜的統計計算。因此,兩種聚合都需要大量計算,因此應正確配置以快速工作。但是,一旦在本教程的幫助下掌握了它們,您將獲得一個強大的工具,可以在應用程序中構建非常有用的功能並從數據集中獲取有用的見解。讓我們開始吧!
在教程開始,我們假定您已經把Elasticsearch及Kibana完整地安裝好了。
創建Index mapping
為了說明significant terms和significant text的工作方式,我們首先需要創建一個測試“news”索引來存儲新聞文章的集合。 索引映射將包含諸如作者,出版日期,文章標題,視圖數和主題之類的字段。 讓我們創建映射:
PUT news
{
"mappings": {
"properties": {
"published": {
"type": "date",
"format": "dateOptionalTime"
},
"author": {
"type": "keyword"
},
"title": {
"type": "text"
},
"topic": {
"type": "keyword"
},
"views": {
"type": "integer"
}
}
}
}
如您所見,我們在topic和author字段中使用了keyword數據類型,在title字段中使用了text數據類型。 提醒您,關鍵字字段只能按其確切值進行搜索,而文本字段可用於全文搜索。
接下來,讓我們使用Bulk API將一些任意新聞文檔添加到索引中。
POST news/_bulk
{"index":{"_index":"news"}}
{"author":"John Michael","published":"2018-07-08","title":"Tesla is flirting with its lowest close in over 1 1/2 years (TSLA)","topic":"automobile","views":"431"}
{"index":{"_index":"news"}}
{"author":"John Michael","published":"2018-07-22","title":"Tesla to end up like Lehman Brothers (TSLA)","topic":"automobile","views":"1921"}
{"index":{"_index":"news"}}
{"author":"John Michael","published":"2018-07-29","title":"Tesla (TSLA) official says that they are going to release a new self-driving car model in the coming year","topic":"automobile","views":"1849"}
{"index":{"_index":"news"}}
{"author":"John Michael","published":"2018-08-14","title":"Five ways Tesla uses AI and Big Data","topic":"ai","views":"871"}
{"index":{"_index":"news"}}
{"author":"John Michael","published":"2018-08-14","title":"Toyota partners with Tesla (TSLA) to improve the security of self-driving cars","topic":"automobile","views":"871"}
{"index":{"_index":"news"}}
{"author":"Robert Cann","published":"2018-08-25","title":"Is AI dangerous for humanity","topic":"ai","views":"981"}
{"index":{"_index":"news"}}
{"author":"Robert Cann","published":"2018-09-13","title":"Is AI dangerous for humanity","topic":"ai","views":"871"}
{"index":{"_index":"news"}}
{"author":"Robert Cann","published":"2018-09-27","title":"Introduction to Generative Adversarial Networks (GANs) in self-driving cars","topic":"automobile","views":"1183"}
{"index":{"_index":"news"}}
{"author":"Robert Cann","published":"2018-10-09","title":"Introduction to Natural Language Processing","topic":"ai","views":"786"}
{"index":{"_index":"news"}}
{"author":"Robert Cann","published":"2018-10-15","title":"New Distant Objects Found in the Fight for Planet X ","topic":"astronomy","views":"542"}
在這里,我們共同插入了20條數據。
Significant Terms Aggregation
正如我們已經提到的,重要的術語聚合可以識別數據中異常和有趣的術語。 對於以下用例,聚合功能非常強大:
- 識別與用戶查詢相關的相關術語/文檔。 例如,當用戶查詢“Spain”時,聚合可能會建議諸如“Madrid”,“Corrida”之類的術語,或有關Spain的文檔中常見的其他任何術語。
- Significant term聚合可用於自動新聞分類器,其中基於頻繁連接的術語圖對文檔進行分類。
- 發現數據中的異常。 例如,借助這種匯總,我們可以識別某些地理區域中的異常犯罪類型或疾病。
重要的是要理解,significant terms聚合選擇的術語不僅是文檔集中最受歡迎的術語。 例如,即使首字母縮略詞“ MSFT”僅存在於一千萬個文檔索引中的10個文檔中,但如果在與用戶查詢“ Microsoft”相匹配的50個文檔中有10個找到了這個MSFT,則它仍然是相關的。 該頻率使acronym(比如MSFT)與用戶的搜索相關。
為了識別重要術語,聚合對與查詢匹配的搜索結果以及從中收集結果的索引執行復雜的統計分析。 與查詢直接匹配的搜索結果代表前景集,而從中檢索它們的索引代表背景集。 重要術語聚合的任務是比較這些集合並找到最常與用戶查詢關聯的術語。
上面的意思可以用上面的一幅圖來解釋。比如上面的綠色代表一個很大的索引,它里面可能含有比如Nokia這個term很高的出現率。即便如此,只要我們所搜索的FG那個紅色的結果里,它出現的幾率非常低,也不能夠出現在significant terms的聚合里。相反,如果一個term比如TECNO(中國一個非常出名的在非洲的品牌)出現我們所搜索的set里(比如搜索 africa phone),那么我們搜索的聚合將會是是TECNO盡管TECNO可能在整個BG所包含的文檔里出現的幾率非常之低。
讓我們使用真實示例,演示聚合如何工作。 在下面的示例中,我們將嘗試在索引中查找每個author的重要topics。 為此,我們首先在author字段上使用術語“桶聚合(bucket aggregation)”。 您還記得,terms aggregation為找到索引的所有唯一術語(即author)構造了存儲桶。 接下來,我們在“topics”字段上使用significant terms聚合,以找出每個author的最重要topic。 看一下下面的查詢:
GET news/_search
{
"size": 0,
"aggregations": {
"authors": {
"terms": {
"field": "author"
},
"aggregations": {
"significant_topic_types": {
"significant_terms": {
"field": "topic"
}
}
}
}
}
}
顯示的結果為:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 20,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"authors" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "John Michael",
"doc_count" : 10,
"significant_topic_types" : {
"doc_count" : 10,
"bg_count" : 20,
"buckets" : [
{
"key" : "automobile",
"doc_count" : 8,
"score" : 0.4800000000000001,
"bg_count" : 10
}
]
}
},
{
"key" : "Robert Cann",
"doc_count" : 10,
"significant_topic_types" : {
"doc_count" : 10,
"bg_count" : 20,
"buckets" : [
{
"key" : "ai",
"doc_count" : 6,
"score" : 0.2999999999999999,
"bg_count" : 8
}
]
}
}
]
}
}
}
顯然對於作者John Michael來說,在他所發表的書里automobile是最經常出現的詞。共有8次,而bg_count是10。同樣對於作者Robert Cann來說,在他發布的作品里,ai是最最經常出現的詞,在他的8個作品中,有6詞提到ai。可以斷定他就是一個ai專家!
針對上面的significant terms聚合查詢,我們也可以通過如下的方法來查詢針對某個作者(author)的聚合。
GET news/_search
{
"size": 0,
"query": {
"term": {
"author": "John Michael"
}
},
"aggregations": {
"significant_topics": {
"significant_terms": {
"field": "topic"
}
}
}
}
顯示的結果為:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"significant_topics" : {
"doc_count" : 10,
"bg_count" : 20,
"buckets" : [
{
"key" : "automobile",
"doc_count" : 8,
"score" : 0.4800000000000001,
"bg_count" : 10
}
]
}
}
}
這種表述更適合解釋我們上面的那個BG和FG的圖。
針對significant text aggregation,基本它和significant terms aggregation非常相似,只是它作用於一個text字段而不是一個keyword字段。比如:
GET news/_search
{
"size": 0,
"query": {
"match": {
"title": "Tesla ai"
}
},
"aggregations": {
"significant_topics": {
"significant_text": {
"field": "topic"
}
}
}
}
注意這里的title字段是text,它同時搜索Telsa及ai,再根據這兩個詞來進行聚合:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 14,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"significant_topics" : {
"doc_count" : 14,
"bg_count" : 20,
"buckets" : [
{
"key" : "automobile",
"doc_count" : 8,
"score" : 0.08163265306122446,
"bg_count" : 10
},
{
"key" : "ai",
"doc_count" : 6,
"score" : 0.030612244897959134,
"bg_count" : 8
}
]
}
}
}
參考:
【1】significant terms aggregation(https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-significantterms-aggregation.html)
【2】significant text aggregation(https://www.elastic.co/guide/en/elasticsearch/reference/master/search-aggregations-bucket-significanttext-aggregation.html)