Elasticsearch 連接查詢


在一般的關系型數據庫中,都支持連接操作。

在ES這種分布式方案中進行連接操作,代價是十分昂貴的。

不過ES也提供了相類似的操作,支持水平任意擴展,實現連接的效果。

其他內容,參考Elasticsearch官方指南整理

ES中的連接

在ES中支持兩種連接方式:嵌套查詢 has_child、has_parent父子查詢

嵌套查詢:

文檔中包含嵌套的字段,這些字段以數組的形式保存對象,這樣每個嵌套的子對象都可以被搜索。

has_child、has_parent父子查詢:

父子文檔是存儲在同一個索引中的不同類型,在索引數據前定義父子關系。在父子查詢中,父子關系通過類型引用。

嵌套查詢

嵌套類型需要實現定義好mapping:

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

定義好后,type1中就有了obj1這個子對象,然后就可以通過嵌套查詢查詢相關的內容:

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

注意其中幾個參數:

1 path 定義了嵌套的對象

2 score_mode 定義里嵌套對象計算的分數與當前查詢分數的處理方式,有avg,sum,max,min以及none。none就是不做任何處理,其他的看字面意思就好理解。

3 query/filter是查詢的方式,內部定義了針對嵌套對象的查詢,注意內部的查詢一定要是用全路徑,即針對obj1的name字段的查詢,要寫obj1.name。

嵌套查詢會在執行子查詢的時候自動觸發,然后把結果返回給當前文檔的查詢。

 

父子查詢

父子關系也需要在之前定義mapping,不過與一般的映射不同,它的定義方式如下:

PUT my_index
{
  "mappings": {
    "my_parent": {},
    "my_child": {
      "_parent": {
        "type": "my_parent" 
      }
    }
  }
}

PUT my_index/my_parent/1 
{
  "text": "This is a parent document"
}

PUT my_index/my_child/2?parent=1 
{
  "text": "This is a child document"
}

PUT my_index/my_child/3?parent=1 
{
  "text": "This is another child document"
}

GET my_index/my_parent/_search
{
  "query": {
    "has_child": { 
      "type": "my_child",
      "query": {
        "match": {
          "text": "child document"
        }
      }
    }
  }
}

這樣就代表,my_child這個類型的父類型是my_parent,這樣就聲明了一種父子關系。然后再索引數據時,指定父子對應的關系。

has_child查詢

這個查詢會檢查子文檔,如果子文檔滿足查詢條件,則返回父文當。

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

通過score_mode字段,可以指定子文檔返回的分值的處理方式。與嵌套類似,它也有avg,sum,max,min和none幾種方式。

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

另外,也可以指定子文檔匹配的最小數目和最大數目。

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

has_parent查詢

has_parent查詢與has_child類似,它是去檢查父文檔那個是否匹配,然后返回父文檔對應的子文檔。

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

 

參考

1 如何定義父子關系:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-parent-field.html

2 連接查詢:https://www.elastic.co/guide/en/elasticsearch/reference/current/joining-queries.html

3 Nested查詢:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

4 Has_Child查詢:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html

5 Has_Parent查詢:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html


免責聲明!

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



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