08.join查询

1. jion查询简介

join查询主要是针对有parent/child文档查询的需求,parent和child是两个独立存储的doc,在es中有两种mapping可以实现,一种是nested mapping,一种是join mapping

2. nested mapping对应的查询

1.使用样例简介

PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "obj1": {
        "type": "nested"
      }
    }
  }
}

GET /my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "obj1",
      "query": {
        "bool": {
          "must": [
            { "match": { "obj1.name": "blue" } },
            { "range": { "obj1.count": { "gt": 5 } } }
          ]
        }
      },
      "score_mode": "avg"
    }
  }
}

可以有的参数
path: 要查询的nested object的属性路径
query: 想要在nested object中进行的查询,如果查到了,会返回root parent doc.
score_mode: 如果一个nested query 命中了root parent doc中的多个child,那么root parent doc的得分如果通过这些child计算出来,
avg: (默认)所有child的平均值
max: max(child_score)
min: min(child_score)
mone: parent doc的score设置为0
sum: sum(child_score)
ignore_unmapped:忽略unmapped path, 默认为false,在path是一个unmapped field的时候会报错

2.多层级的nested query


PUT /drivers
{
  "mappings": {
    "properties": {
      "driver": {
        "type": "nested",
        "properties": {
          "last_name": {
            "type": "text"
          },
          "vehicle": {
            "type": "nested",
            "properties": {
              "make": {
                "type": "text"
              },
              "model": {
                "type": "text"
              }
            }
          }
        }
      }
    }
  }
}

PUT /drivers/_doc/1
{
  "driver" : {
        "last_name" : "McQueen",
        "vehicle" : [
            {
                "make" : "Powell Motors",
                "model" : "Canyonero"
            },
            {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
            }
        ]
    }
}

PUT /drivers/_doc/2?refresh
{
  "driver" : {
        "last_name" : "Hudson",
        "vehicle" : [
            {
                "make" : "Mifune",
                "model" : "Mach Five"
            },
            {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
            }
        ]
    }
}

执行查询

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

response

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 3.7349272,
    "hits" : [
      {
        "_index" : "drivers",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 3.7349272,
        "_source" : {
          "driver" : {
            "last_name" : "McQueen",
            "vehicle" : [
              {
                "make" : "Powell Motors",
                "model" : "Canyonero"
              },
              {
                "make" : "Miller-Meteor",
                "model" : "Ecto-1"
              }
            ]
          }
        }
      }
    ]
  }
}

3. join field的使用

1. has_child 查询简介

has_child查询需要通过join mapping的field来进行支持,这个查询主要是查询拥有某些child的parent文档

PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "my-join-field": {
        "type": "join",
        "relations": {
          "parent": "child"  # 这里可以是任何字符串,前面的代表parent,后面的代表child
        }
      }
    }
  }
}
 

GET /_search
{
  "query": {
    "has_child": {
      "type": "child",
      "query": {
        "match_all": {}
      },
      "max_children": 10,
      "min_children": 2,
      "score_mode": "min"
    }
  }
}

这个文档因为对child的查询是match_all,所以会返回所有有child的parent doc。

参数
type: join field中child的名字(这里刚好也定义为了child,可以是是任何字符串)
query: 想要查询的child,会返回这些child 对应的parent doc
max_child: 设置的话则parent的child数量不能超过这个值
min_child: 设置的话则parent的child数量要大于这个值
score_mode: 如果一个 query 命中了parent doc中的多个child,那么 parent doc的得分如果通过这些child计算出来,
avg: (默认)所有child的平均值
max: max(child_score)
min: min(child_score)
mone: parent doc的score设置为0
sum: sum(child_score)

1. 排序sort

如果想要排序的话,只能使用function_score 来通过_score排序, 不能用正常的sort语法

GET /_search
{
  "query": {
    "has_child": {
      "type": "child",
      "query": {
        "function_score": {
          "script_score": {
            "script": "_score * doc['click_count'].value"
          }
        }
      },
      "score_mode": "max"
    }
  }
}

2. has_parent查询简介

has_parent查询需要通过join mapping的field来进行支持,这个查询主要是查询拥有某些parent的child文档

PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "my-join-field": {
        "type": "join",
        "relations": {
          "parent": "child"
        }
      },
      "tag": {
        "type": "keyword"
      }
    }
  }
} 

GET /my-index-000001/_search
{
  "query": {
    "has_parent": {
      "parent_type": "parent",
      "query": {
        "term": {
          "tag": {
            "value": "Elasticsearch"
          }
        }
      }
    }
  }
}

会在parent中查询tag value为Elasticsearch 的doc,然后查询这些doc对应的child doc

参数
type: join field中parent的名字(这里刚好也定义为了parent,可以是是任何字符串)
query: 想要查询的parent,会返回这些parent 对应的parent doc
score: 默认是false,false的话会忽略parent的相关性得分,ture的话parent的相关性得分会给child使用

1. 排序sort

如果想要排序的话,只能使用function_score 来通过_score排序, 不能用正常的sort语法

GET /_search
{
  "query": {
    "has_parent": {
      "parent_type": "parent",
      "score": true,
      "query": {
        "function_score": {
          "script_score": {
            "script": "_score * doc['view_count'].value"
          }
        }
      }
    }
  }
}

3. parent id查询

PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "my-join-field": {
        "type": "join",
        "relations": {
          "my-parent": "my-child"
        }
      }
    }
  }
}

PUT /my-index-000001/_doc/1?refresh
{
  "text": "This is a parent document.",
  "my-join-field": "my-parent"
}

PUT /my-index-000001/_doc/2?routing=1&refresh
{
  "text": "This is a child document.",
  "my_join_field": {
    "name": "my-child",
    "parent": "1"
  }
}

GET /my-index-000001/_search
{
  "query": {
      "parent_id": {
          "type": "my-child",
          "id": "1"
      }
  }
}


type: 关系中child的名称
id: parent doc的id

返回对应的parent的child doc集合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值