Elasticsearch中的嵌套查詢介紹及實例


大家在工作中想必也接觸過Elasticsearch,今天介紹一下es中的嵌套對象及對應的查詢方式。

 

從考慮一個業務場景開始吧,業務上需要把某些類似的商品聚合成為一個關聯組,需要支持根據某個商品的特征,查詢到它所在的關聯組,es中的存儲結構如下:

{
    "memberGoods":[
        {
            "title":"商品A",
            "brand":"a"
        },
        {
            "title":"商品B",
            "brand":"b"
        }
    ],
    "groupId":"A"
}

那么問題來了,如果memberGoods是一個普通的Object類型,對於下面的查詢條件:

{
    "query":{
        "bool":{
            "must":[
                {
                    "match":{
                        "title":"商品A"
                    }
                },
                {
                    "match":{
                        "brand":"b"
                    }
                }
            ]
        }
    }
}

上面的數據依然會匹配上,但是商品A的品牌應該是a,而不是b呀,造成這種現象的原因是結構性的JSON文檔會平整成索引內的一個簡單鍵值格式,就像這樣:

{
    "memberGoods.title":[
        "商品A",
        "商品B"
    ],
    "memberGoods.brand":[
        "a",
        "b"
    ],
    "groupId":"A"
}

顯然,如上的數據損失了同一商品數據之間的關聯性,從而出現了交叉匹配的現象,為解決這一問題,nested Object應運而生,它保留了子文檔數據中的關聯性,如果memberGoods的數據格式被定義為nested,那么每一個nested object 將會作為一個隱藏的單獨文本建立索引。如下:

{
     "groupId":"A"
},
{
     "memberGoods.title":"商品A",
     "memberGoods.brand":"a"
},
{
     "memberGoods.title":"商品B",
     "memberGoods.brand":"b"
}

通過分開給每個nested object建索引,object內部的字段間的關系就能保持。當執行查詢時,只會匹配’match’同時出現在相同的nested object的結果。

不僅如此,由於nested objects 建索引的方式,在查詢的時候將根文本和nested文檔拼接是很快的,就跟把他們當成一個單獨的文本一樣的快。

 

nested object作為一個獨立隱藏文檔單獨建索引,因此,我們不能直接查詢它們。取而代之,我們必須使用nested查詢或者nested filter來接觸它們,java語言描述如下:

 

               queryBuilder.must(QueryBuilders.nestedQuery("memberGoods"/** nested 字段*/,
                        QueryBuilders.matchPhraseQuery("memberGoods.title", "商品A"), ScoreMode.Avg));

 

其中memberGoods是父字段,memberGoods.title是子字段,以上已有提及,最后的參數ScoreMode.Avg是父文檔匹配分數的設定,(Parent hit's score is the average/max/sum/min of all child scores.)

 

此外,nested形式的查詢也有一些需要注意的缺點:

1.增加,改變或者刪除一個nested文本,整個文本必須重新建索引。nested文本越多,代價越大。

2.檢索請求會返回整個文本,而不僅是匹配的nested文本。盡管有計划正在執行以能夠支持返回根文本的同時返回最匹配的nested文本,但目前還未實現。

 

--------------------------------------------

更多詳細內容,請參考es官方文檔:

https://www.elastic.co/guide/en/elasticsearch/guide/master/nested-objects.html

https://www.elastic.co/guide/en/elasticsearch/guide/master/index.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM