Link Search Menu Expand Document Documentation Menu

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"
          }
        }
      }
    ]
  }
}

后续步骤

剩余 350 字符

有问题?

想做贡献?