Elasticsearch 搜索 child 及其所有按 parent 分组的同级文档

Elasticsearch search for a child and all his sibling documents grouped by parent

我希望能够提交匹配 child 文档和 returns parent 及其所有 child 文档的查询。

我的 Elasticsearch 索引中有 parent 和 child 文档通过连接关联:https://www.elastic.co/guide/en/elasticsearch/reference/current/parent-join.html?baymax=rec&rogue=rec-1&elektra=guide.

我将项目分成几组,我索引中的每个项目都是一个单独的 child 文档(注意:需要能够通过不同的查询分别搜索 children,所以我 不能使用嵌套 objects)。 parent 文档包含一些有意义的字段,例如 (name, sku, image) 因此需要获取 Parent 及其 children.

我已经使用以下查询实现了我的要求:

GET my_index/_search
{
  "query": {
    "has_child": {
      "type": "child",
      "query": {
        "has_parent": {
          "parent_type": "parent",
          "query": {
            "has_child": {
              "type": "child",
              "query": {
                "multi_match": {
                  "query": "NV1540JR",
                  "fields": [
                    "name",
                    "sku"
                  ]
                }
              }
            }
          }
        }
      },
      "inner_hits": {}
    }
  }
}

结果是returns,正是我需要的:

{
    "took": 301,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.0,
        "hits": [
            {
                "_index": "my_index",
                "_type": "_doc",
                "_id": "Az9GEAT",
                "_score": 1.0,
                "_source": {
                    "id": "Az9GEAT",
                    "name": "Gold Calacatta 2.0",
                    "sku": "NV1540",
                    "my_join-field": "parent"
                },
                "inner_hits": {
                    "child": {
                        "hits": {
                            "total": {
                                "value": 2,
                                "relation": "eq"
                            },
                            "max_score": 1.0,
                            "hits": [
                                {
                                    "_index": "my_index",
                                    "_type": "_doc",
                                    "_id": "zx9EEAR",
                                    "_score": 1.0,
                                    "_routing": "Az9GEAT",
                                    "_source": {
                                        "id": "zx9EEAR",
                                        "name": "Gold Calacatta 12\" x 24\"",
                                        "sku": "NV1540M-2",
                                        "familyName": "Gold Calacatta 2.0",
                                        "familySku": "NV1540",
                                        "my_join-field": {
                                            "name": "child",
                                            "parent": "Az9GEAT"
                                        }
                                    }
                                },
                                {
                                    "_index": "my_index",
                                    "_type": "_doc",
                                    "_id": "Az9NEAT",
                                    "_score": 1.0,
                                    "_routing": "Az9GEAT",
                                    "_source": {
                                        "id": "Az9NEAT",
                                        "name": "Gold Calacatta 2.0, 24\" x 48\"",
                                        "sku": "NV1540JR",
                                        "familyName": "Gold Calacatta 2.0",
                                        "familySku": "NV1540",
                                        "my_join-field": {
                                            "name": "child",
                                            "parent": "Az9GEAT"
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        ]
    }
}

我可以通过其他方式实现 Application-side 加入,方法是进行三个不同的查询调用(一个获取所有匹配数据,第二个获取兄弟姐妹,第三个获取 parents)并将结果合并到我的应用程序。但不确定它会更快,因为 http 请求时间和数据处理时间。

所以,我是 elasticsearch 的新手,无法估计它有多糟糕。它如何影响查询性能?是否还有其他方法可以得到想要的结果?或者如何改进我的查询?我很高兴听到任何建议或想法!谢谢

对于 ES,标准做法是检索 object 个 ID 列表并对 return 完整文档集执行第二个请求。

您可以使用 2 个查询来实现您的逻辑

  1. 请求 (1) 所有满足您的 child 搜索条件的文档。 Select 仅 child.idchild.parent_id 字段以确保您仅加载索引数据,未搜索文档 _source。请求会比较快
  2. 在您的应用程序代码中确定 parent_ids & orphaned_child_ids
  3. 的唯一列表
  4. 请求 (2) 所有满足条件的文档:parent_id in parent_idsparent_id = NULL AND child_id in orphaned_child_ids