Elasticsearch 聯結查詢(joining queries)

Neil Zhu,簡書ID Not_GOD,University AI 創始人 & Chief Scientist,致力于推進世界人工智能化進程。制定并實施 UAI 中長期增長戰略和目標,帶領團隊快速成長為人工智能領域最專業的力量。
作為行業領導者,他和UAI一起在2014年創建了TASA(中國最早的人工智能社團), DL Center(深度學習知識中心全球價值網絡),AI growth(行業智庫培訓)等,為中國的人工智能人才建設輸送了大量的血液和養分。此外,他還參與或者舉辦過各類國際性的人工智能峰會和活動,產生了巨大的影響力,書寫了60萬字的人工智能精品技術內容,生產翻譯了全球第一本深度學習入門書《神經網絡與深度學習》,生產的內容被大量的專業垂直公眾號和媒體轉載與連載。曾經受邀為國內頂尖大學制定人工智能學習規劃和教授人工智能前沿課程,均受學生和老師好評。

在像 Elasticsearch 這樣的分布式計算系統執行全 SQL 風格的聯結操作代價昂貴。相應地,Elasticsearch 提供了兩種形式的聯結可以實現水平規模的擴展。

  • 嵌套查詢 nested query:文檔包含 nested 類型的字段。這些字段用來索引數組對象,其中每個對象作為獨立的文檔可以被檢索(使用 nested 查詢)。
  • has_childhas_parent 查詢:父子關系可以在一個單獨的索引中的兩個文檔類型間存在。has_child 查詢返回了父文檔,其子文檔匹配了特定的查詢。而 has_parent 查詢返回子文檔,其父文檔匹配了特定的查詢。

參考 terms-lookup mechanism,也可以讓你從另一個文檔中值中構建一個 terms 查詢。

Nested Query

嵌套查詢可以查詢嵌套的對象/文檔(參考 nested mapping)。查詢是針對當做是內部按照分隔的文檔索引的嵌套對象/文檔進行的,返回根 parent 文檔(或者 parent 嵌套映射)。這里是一個映射的例子:

{
    "type1" : {
        "properties" : {
            "obj1" : {
                "type" : "nested"
            }
        }
    }
}

這里是一個嵌套查詢的例子:

{
    "nested" : {
        "path" : "obj1",
        "score_mode" : "avg",
        "query" : {
            "bool" : {
                "must" : [
                    {
                        "match" : {"obj1.name" : "blue"}
                    },
                    {
                        "range" : {"obj1.count" : {"gt" : 5}}
                    }
                ]
            }
        }
    }
}

這個查詢的 path 指向了嵌套的對象路徑,而 query 或者 filter 包含了會在匹配了直接的路徑并且和根 parent 文檔連接的嵌套的文檔上運行。注意,任何在這個查詢內部引用的字段必須使用完整的路徑。

score_mode 使得我們可以設置內部 children 匹配影響 parent 文檔。默認是 avg,但是也可以設置為 summinmaxnone

多層嵌套自動支持,檢查,并產生一個內部的嵌套查詢來自動匹配相關的嵌套層級(不是根 root)如果存在在另一個嵌套查詢中。

Has Child Query

has_child 過濾器接受一個查詢和 child 類型來執行,產生 parent 文檔擁有匹配查詢的 child 文檔。這里是例子:

{
    "has_child" : {
        "type" : "blog_tag",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

打分能力

has_child 查詢同樣有打分的支持。支持的模式有 minmaxtotalavg 或者 none。默認的模式是 none 會產生同樣的行為。如果打分模式設成了另外一種,那么所有匹配的 child 文檔的分數都會被聚合在關聯的 parent 文檔上。打分類型可以使用 score_mode 字段在 has_child 查詢內部指定:

{
    "has_child" : {
        "type" : "blog_tag",
        "score_mode" : "sum",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

Min/Max Children

has_child 查詢允許我們指定最小/最大數目的 children 需要匹配來讓 parent doc 被當做是一個匹配:

{
    "has_child" : {
        "type" : "blog_tag",
        "score_mode" : "sum",
        "min_children": 2, 
        "max_children": 10, 
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

min_childrenmax_children 都是可選的。

min_childrenmax_children 參數可以和 score_mode 參數組合使用。

Has Parent Query

has_parent 查詢接受查詢和 parent 類型。查詢是在 parent 文檔空間上進行的,這個是通過 parent 類型指定的。該查詢返回和關聯的 parent 文檔匹配的 child 文檔。剩下的設置都和 has_child 查詢相同。

{
    "has_parent" : {
        "parent_type" : "blog",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}

打分能力

has_parent 同樣也有打分支持。支持的打分類型就是 score 或者 none。默認是 none,忽略了來自 parent 文檔的分數。這里的分數和 has_parent 查詢相同。如果打分類型設置為 score,那么匹配的 parent 文檔的分數就被聚合在 child 文檔中屬于匹配的 parent 文檔。打分模式可以使用 score_modehas_parent query 中指定:

{
    "has_parent" : {
        "parent_type" : "blog",
        "score_mode" : "score",
        "query" : {
            "term" : {
                "tag" : "something"
            }
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容