父查询

父查询 #

has_parent 查询返回匹配特定查询的父文档的子文档。您可以通过使用连接字段类型在相同索引中的文档之间建立父子关系。

has_parent 查询比其他查询慢,因为它执行了连接操作。随着匹配的父文档数量的增加,性能会降低。您搜索中的每个 has_parent 查询都可能显著影响查询性能。如果您优先考虑速度,请避免使用此查询或尽可能限制其使用。

参考样例 #

在您运行一个 has_parent 查询之前,您的索引必须包含一个连接字段,以便建立父子关系。索引映射请求使用以下格式:

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_mode可选指示匹配的父级文档的相关性分数是否汇总到其子文档中。如果 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"
          }
        }
      }
    ]
  }
}