Elasticsearch系列(15)Query之连接查询

2020-09-17  本文已影响0人  正义的杰克船长

1. 前言

在Elasticsearch这种分布式系统上执行完全类似SQL风格的连接查询代价比较高,作为替代,Elasticsearch提供了两种可水平伸缩的连接(Join)形式的查询。

2. 嵌套查询

嵌套查询(nested query)搜索嵌套(nested)类型的字段对象,就好像它们被索引为单独的文档一样。如果一个对象匹配搜索条件,嵌套查询将返回对象所在的父文档。
首先创建包含嵌套类型的映射的索引,示例如下:

PUT /my_index_01
{
    "mappings" : {
        "properties" : {
            "my_object" : {
                "type" : "nested"
            }
        }
    }
}
PUT /my_index_01/_doc/1
{
    "my_object" : [
      {"name": "blue", "count": 10},
      {"name": "red", "count": 1},
      {"name": "yellow", "count": 20}
    ]
}

通过嵌套查询,示例如下:

GET /my_index_01/_search
{
    "query":  {
        "nested" : {
            "path" : "my_object",
            "query" : {
                "bool" : {
                    "must" : [
                      { "match" : {"my_object.name" : "blue"} },
                      { "range" : {"my_object.count" : {"gt" : 5}} }
                    ]
                }
            },
            "score_mode" : "avg"
        }
    }
}
nested查询顶级参数
多级嵌套查询

首先定义一个多级嵌套索引并索引数据,示例如下:

PUT /my_index_02
{
  "mappings": {
    "properties": {
      "driver": {
        "type": "nested",
        "properties": {
          "last_name": {
            "type": "text"
          },
          "vehicle": {
            "type": "nested",
            "properties": {
              "make": {
                "type": "text"
              },
              "model": {
                "type": "text"
              }
            }
          }
        }
      }
    }
  }
}
PUT /my_index_02/_doc/1
{
  "driver": {
    "last_name": "McQueen",
    "vehicle": [
      {
        "make": "Powell Motors",
        "model": "Canyonero"
      },
      {
        "make": "Miller-Meteor",
        "model": "Ecto-1"
      }
    ]
  }
}
PUT /my_index_02/_doc/2?refresh
{
  "driver": {
    "last_name": "Hudson",
    "vehicle": [
      {
        "make": "Mifune",
        "model": "Mach Five"
      },
      {
        "make": "Miller-Meteor",
        "model": "Ecto-1"
      }
    ]
  }
}

多级嵌套查询,示例如下:

GET /my_index_02/_search
{
  "query": {
    "nested": {
      "path": "driver",
      "query": {
        "nested": {
          "path": "driver.vehicle",
          "query": {
            "bool": {
              "must": [
                {"match": { "driver.vehicle.make": "Powell Motors" }},
                {"match": { "driver.vehicle.model": "Canyonero" }}
              ]
            }
          }
        }
      }
    }
  }
}

3. has_child查询

如果连接(join)的子文档与所输入的查询匹配,那么返回父文档,可以使用连接(join)字段映射在同一个索引的文档之间创建父子关系,如果要使用has_child查询,索引必须包含一个连接(join)字段映射。
使用has_child查询,首先创建包含连接(join)类型字段的索引,示例如下:

PUT /my_index_03
{
  "mappings": {
    "properties": {
      "my_num": {
        "type": "keyword"
      },
      "view_count": {
        "type": "integer"
      },
      "my-join-field": {
        "type": "join",
        "relations": {
          "parent": "child"
        }
      }
    }
  }
}

然后索引父文档和子文档,示例如下:

# 创建父文档
PUT /my_index_03/_doc/1
{"my_num":"001", "view_count": 10, "my-join-field":{"name":"parent"}}
# 创建子文档,parent指定父文档id
PUT /my_index_03/_doc/2?routing=1&refresh
{
  "my_num": "002",
  "view_count": 5,
  "my-join-field": {
    "name": "child",
    "parent": "1"
  }
}

使用has_child查询来查询文档中子文档匹配条件的文档,示例如下:

GET my_index_03/_search
{
  "query": {
    "has_child": {
      "type": "child",
      "query": {
        "match_all": {}
      },
      "max_children": 10,
      "min_children": 1,
      "score_mode": "min"
    }
  }
}
has_child查询顶级参数
排序
GET my_index_03/_search
{
  "query": {
    "has_child": {
      "type": "child",
      "query": {
        "function_score": {
          "script_score": {
            "script": "_score * doc['view_count'].value"
          }
        }
      },
      "score_mode": "max"
    }
  }
}

4. has_parent查询

如果连接(join)的父文档与所输入的查询匹配,那么返回子文档,可以使用连接(join)字段映射在同一个索引的文档之间创建父子关系。如果要使用has_parent查询,索引必须包含一个连接(join)字段映射。(与has_child查询用法类似)
使用has_parent查询,查询my_index_03索引中,文档的父文档中字段“my_num”值为“001”的子文档,示例如下:

GET /my_index_03/_search
{
  "query": {
    "has_parent": {
      "parent_type": "parent",
      "query":{"term":{"my_num":{"value":"001"}}}
    }
  }
}

返回匹配的子文档,结果片段如下:

has_parent查询顶级参数
排序
GET /my_index_03/_search
{
  "query": {
    "has_parent": {
      "parent_type": "parent",
      "score" : true,
      "query" : {
          "function_score" : {
              "script_score": {
                  "script": "_score * doc['view_count'].value"
              }
          }
      }
    }
  }
}

5. 父ID查询

parent_id查询返回匹配指定父ID的子文档。
例如,在my_index_03索引中,查询父ID等于1的子文档,示例如下:

GET /my_index_03/_search
{
  "query": {
    "parent_id": {
      "type": "child",
      "id": "1"
    }
  }
}
parent_id查询顶级参数
上一篇 下一篇

猜你喜欢

热点阅读