在Elasticsearch中使用嵌套映射与父子关系

时间:2017-09-20 04:16:12

标签: elasticsearch elasticsearch-dsl elasticsearch-dsl-py

目前在我的ES文档结构中,有一个类型为'Object'的字段。这是一个json对象,里面最多可以有3000个字段。问题在于,由于文档太大,我的ES内存不足。所以我希望改变我的文档结构。

我正在研究的两个结构是 - 嵌套映射和父子关系。这两种结构都满足我的搜索要求。正在考虑的要点:

  1. 我读到嵌套查询比子查询快得多。
  2. 嵌套映射也将嵌套字段另存为单独的文档。
  3. 我面临两点困惑:

    1. 嵌套索引如何工作? ES是否一次性获取整个文档并立即完全分析,或者嵌套文档的请求是个体的。因为在第一种情况下,ES可能会再次耗尽内存。

    2. 当我们说父子查询较慢时,我们的意思有多慢?

    3. 寻找输入。

2 个答案:

答案 0 :(得分:1)

嵌套比父/子更快,更易于管理。事实上,你可以索引没有父母的孩子,所以你在索引时必须小心。此外,当您要删除父项的一个条目时,您必须删除所有子节点,这不是自动任务。 另一方面,如果您要更改/更新您的条目,父母/子女会更舒服。对于嵌套类型,您不能仅更改嵌套字段中的一个嵌套值,您必须重新索引嵌套字段中的所有嵌套值。使用父/子,您也可以更改/更新该父或子字段中的一个值。 嵌套在索引中被视为原子关系数据,而父/子只是保持2字段 - parent,child的关系的不同数据类型。 你可以在这里阅读kimchy帖子,对于父母/孩子的缓慢,你可以阅读讨论的最后一条评论https://discuss.elastic.co/t/choosing-parent-child-vs-nested-document/6742

答案 1 :(得分:0)

嵌套 ::

  1. 嵌套文档彼此存储在同一个 Lucene 块中,这 有助于读取/查询性能。阅读嵌套文档比 等效的父/子。

  2. 更新嵌套文档(父文档或嵌套文档)中的单个字段 children) 强制 ES 重新索引整个嵌套文档。这可以 对于大型嵌套文档来说非常昂贵。

  3. “交叉引用”嵌套文档是不可能的。

  4. 最适合不经常更改的数据。

父/子 ::

  1. 子节点与父节点分开存储,但路由到同一个分片。 因此,父/子在读取/查询上的性能略低于嵌套。

  2. 父/子映射有一点额外的内存开销,因为 ES 维护一个“连接” 内存中的列表。

  3. 更新子文档不会影响父文档或任何其他子文档,这可以 可能会在大型文档上节省大量索引。

  4. 对父/子进行排序/评分可能很困难,因为有孩子/有父母 操作有时可能不透明