【问题标题】:elasticsearch: Get all documents that share the same top-most ancestorelasticsearch:获取共享相同最顶层祖先的所有文档
【发布时间】:2017-09-26 14:46:03
【问题描述】:

我正在尝试获取共享同一个最顶层祖先的所有文档,其中一个孩子可以是多个文档的父母、祖父母、祖父母等。

假设我有一个这样的结构(借自https://www.elastic.co/guide/en/elasticsearch/reference/5.6/parent-join.html):

   (parent)
   question
    /    \
   /      \
comment  answer
(child)  (child)

在代码中:

PUT my_index
{
  "settings": {
    "mapping.single_type": true
  },
  "mappings": {
    "doc": {
      "properties": {
        "my_join_field": {
          "type": "join",
          "relations": {
            "question": ["answer", "comment"]
          }
        }
      }
    }
  }
}

但是,理论上可以永远回答 cmets 和评论答案。假设我有一个问题,其结构如下:

                               (id: 1)
                               question
                              /        \
                             /          \
                        answer          answer
                       (id: 5)          (id: 8)
                       /     \              |
                      /       \             |
                   comment  answer        answer
                  (id: 15) (id: 12)      (id: 9)
                  /    \        |          /   \  
                 /      \       |         /     \ 
              answer  answer  comment  answer  answer 
             (id: 16)(id: 17) (id: 19) (id: 10)(id: 11)

只知道 id 9,如何获取所有文档(ids 1、5、8、9、10、11、12、15、16、17、19)?

【问题讨论】:

  • 由于您试图获取给定文档的所有孩子和父母,我看不出文档 5 下面的分支与文档 9 的相关性。
  • 嗯,就我而言,它非常相关,因为我想获取与 doc 9 相关的所有文档。原因是文档分支更多,然后显示的分支没有连接(并且它们与 doc 9 无关)。
  • 所以,总而言之,您基本上需要获取与 doc 9 属于同一树的所有文档,即与 doc 9 共享相同最顶层祖先的所有文档。跨度>
  • 是的 - 这正是我所需要的(并且根据您的输入更改了问题)!
  • 您可以做的最简单的事情是在树的每个文档中包含一个包含最顶层祖先的 id 的新字段。这样您就可以轻松检索具有该 ID 的所有文档。

标签: elasticsearch


【解决方案1】:

以下是 Elasticsearch documentation 的摘录:

Four common techniques are used to manage relational data in Elasticsearch:

Application-side joins
Data denormalization
Nested objects
Parent/child relationships 

Often the final solution will require a mixture of a few of these techniques.

正如 Val 所建议的,您可以通过引入两个字段来实现应用程序端连接:“top_most_ansestor”和“parent”。这是一个非常合理且简单的解决方案,因为它不需要 Elasticsearch 连接字段。

但是,您可能想要结合技术。

如果您想使用连接字段,那么您可以考虑将最顶层的祖先定义为所有子代、孙代等的父代,并在您的应用程序中维护您的树层次结构。从 Elasticsearch 的角度来看,您将拥有一棵浅而宽的树(单亲,有很多叶子)

question(id 1): [ids 1, 5, 8, 9, 10, 11, 12, 15, 16, 17, 19]

整个树的检索将通过一个请求完成。如上所述,您的应用程序将以不同的方式查看您的文档:深度树。例如。对于文档 9,您将拥有

_id:9 {"parent":8,"text":"some text", "type":"answer"} 

您应该使用哪种技术取决于其他要求和您的偏好。越简单越好。

【讨论】:

  • 感谢您的回答!但是我最终使用了@Val 建议并添加了一个名为 parent_id 的字段。对于每个孩子,我都会调用父母的 parent_id 并将其保存在 parent_id 中。这给我留下了两种额外的可能性,1:我可以跳过使用父/子关系(因为它从 6.0+ 开始贬值)并且可以在 parent_id 上折叠,从而获得统计信息,我在一棵树中有多少个文档(等等。 )。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-24
  • 1970-01-01
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多