Has parent 查询
has_parent
查询返回其父文档与特定查询匹配的子文档。您可以通过使用 join 字段类型,在同一索引中的文档之间建立父/子关系。
has_parent
查询比其他查询慢,因为它执行连接操作。匹配的父文档数量越多,性能下降越明显。搜索中的每个 has_parent
查询都可能显著影响查询性能。如果您优先考虑速度,请避免使用此查询或尽可能限制其使用。
示例
在运行 has_parent
查询之前,您的索引必须包含一个 join 字段,以便建立父/子关系。索引映射请求使用以下格式:
PUT /example_index
{
"mappings": {
"properties": {
"relationship_field": {
"type": "join",
"relations": {
"parent_doc": "child_doc"
}
}
}
}
}
对于此示例,首先配置一个索引,其中包含表示产品及其品牌,如 has_child
查询示例 中所述。
要搜索父级的子级,请使用 has_parent
查询。以下查询返回由匹配查询 economy
的品牌制造的子文档(产品):
GET testindex1/_search
{
"query" : {
"has_parent": {
"parent_type":"brand",
"query": {
"match" : {
"name": "economy"
}
}
}
}
}
响应返回该品牌生产的所有产品:
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "testindex1",
"_id": "4",
"_score": 1,
"_routing": "2",
"_source": {
"name": "Electronic watch",
"sales_count": 300,
"product_to_brand": {
"name": "product",
"parent": "2"
}
}
},
{
"_index": "testindex1",
"_id": "5",
"_score": 1,
"_routing": "2",
"_source": {
"name": "Digital watch",
"sales_count": 100,
"product_to_brand": {
"name": "product",
"parent": "2"
}
}
}
]
}
}
检索内部匹配项
要返回与查询匹配的父文档,请提供 inner_hits
参数:
GET testindex1/_search
{
"query" : {
"has_parent": {
"parent_type":"brand",
"query": {
"match" : {
"name": "economy"
}
},
"inner_hits": {}
}
}
}
响应在 inner_hits
字段中包含父文档:
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 2,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "testindex1",
"_id": "4",
"_score": 1,
"_routing": "2",
"_source": {
"name": "Electronic watch",
"sales_count": 300,
"product_to_brand": {
"name": "product",
"parent": "2"
}
},
"inner_hits": {
"brand": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.3862942,
"hits": [
{
"_index": "testindex1",
"_id": "2",
"_score": 1.3862942,
"_source": {
"name": "Economy brand",
"product_to_brand": "brand"
}
}
]
}
}
}
},
{
"_index": "testindex1",
"_id": "5",
"_score": 1,
"_routing": "2",
"_source": {
"name": "Digital watch",
"sales_count": 100,
"product_to_brand": {
"name": "product",
"parent": "2"
}
},
"inner_hits": {
"brand": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.3862942,
"hits": [
{
"_index": "testindex1",
"_id": "2",
"_score": 1.3862942,
"_source": {
"name": "Economy brand",
"product_to_brand": "brand"
}
}
]
}
}
}
}
]
}
}
有关检索内部匹配项的更多信息,请参阅 内部匹配项。
参数
下表列出了 has_parent
查询支持的所有顶级参数。
参数 | 必需/可选 | 描述 |
---|---|---|
parent_type | 必需 | 指定在 join 字段映射中定义的父关系名称。 |
query | 必需 | 要对父文档运行的查询。如果父文档匹配查询,则返回子文档。 |
ignore_unmapped | 可选 | 指示是否忽略未映射的 parent_type 字段,不返回文档而是抛出错误。在查询多个索引时,您可以提供此参数,其中一些索引可能不包含 parent_type 字段。默认值为 false 。 |
score | 可选 | 指示匹配父文档的相关性分数是否聚合到其子文档中。如果为 false ,则忽略父文档的相关性分数,并且每个子文档被分配一个等于查询 boost (默认为 1 )的相关性分数。如果为 true ,则匹配父文档的相关性分数将聚合到其子文档的相关性分数中。默认值为 false 。 |
inner_hits | 可选 | 如果提供,返回匹配查询的底层匹配项(父文档)。 |
排序限制
has_parent
查询不支持使用标准排序选项排序结果。如果您需要根据子文档父文档中的字段对子文档进行排序,您可以使用 function_score
查询 并按子文档的分数进行排序。
对于前面的示例,首先添加一个 customer_satisfaction
字段,您将根据该字段对属于父(品牌)文档的子文档进行排序:
PUT testindex1/_doc/1
{
"name": "Luxury watch brand",
"product_to_brand" : "brand",
"customer_satisfaction": 4.5
}
PUT testindex1/_doc/2
{
"name": "Economy watch brand",
"product_to_brand" : "brand",
"customer_satisfaction": 3.9
}
现在,您可以根据子文档(产品)的父品牌中的 customer_satisfaction
字段对它们进行排序。此查询将分数乘以父文档的 customer_satisfaction
字段:
GET testindex1/_search
{
"query": {
"has_parent": {
"parent_type": "brand",
"score": true,
"query": {
"function_score": {
"script_score": {
"script": "_score * doc['customer_satisfaction'].value"
}
}
}
}
}
}
响应包含按最高父级 customer_satisfaction
排序的产品:
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 4.5,
"hits": [
{
"_index": "testindex1",
"_id": "3",
"_score": 4.5,
"_routing": "1",
"_source": {
"name": "Mechanical watch",
"sales_count": 150,
"product_to_brand": {
"name": "product",
"parent": "1"
}
}
},
{
"_index": "testindex1",
"_id": "4",
"_score": 3.9,
"_routing": "2",
"_source": {
"name": "Electronic watch",
"sales_count": 300,
"product_to_brand": {
"name": "product",
"parent": "2"
}
}
},
{
"_index": "testindex1",
"_id": "5",
"_score": 3.9,
"_routing": "2",
"_source": {
"name": "Digital watch",
"sales_count": 100,
"product_to_brand": {
"name": "product",
"parent": "2"
}
}
}
]
}
}
后续步骤
- 了解更多关于 检索内部匹配项 的信息。