Elasticsearch关系映射(一对一和一对多)

Aru*_*thi 25 mapping relationship elasticsearch elastica

在我的弹性搜索服务器中,我有一个索引http://localhost:9200/blog.
(博客)索引包含多种类型.

例如:http://localhost:9200/blog/posts,http://localhost:9200/blog/tags.

在标签类型中,我创建了超过1000个标签和10个帖子类型的帖子.

例如:帖子

{   
    "_index":"blog",
    "_type":"posts",
    "_id":"1",
    "_version":3,
    "found":true,
    "_source" : {
        "catalogId" : "1",
       "name" : "cricket",
       "url" : "http://www.wikipedia/cricket"
    }
}
Run Code Online (Sandbox Code Playgroud)

例如:标签

{   
    "_index":"blog",
    "_type":"tags",
    "_id":"1",
    "_version":3,
    "found":true,
    "_source" : {
        "tagId" : "1",
        "name" : "game"
    }
}
Run Code Online (Sandbox Code Playgroud)

我想将现有标签分配给博客帖子(即relationship => mapping).

如何将标签分配给帖子映射?

Pai*_*ook 56

您可以在Elasticsearch中使用4种方法来管理关系.它们在Elasticsearch博客文章中有很好的概述 - 管理Elasticsearch内部的关系我建议阅读整篇文章以获得有关每种方法的更多详细信息,然后选择最符合您业务需求的方法,同时保持技术上的合理性.

以下是4种方法的亮点.

内在对象

  • 简单,快速,高效
  • 仅在维持一对一关系时适用
  • 无需特殊查询

嵌套

  • 嵌套文档彼此存储在相同的Lucene块中,这有助于读取/查询性能.读取嵌套文档比等效父/子快.
  • 更新嵌套文档(父级或嵌套子级)中的单个字段会强制ES重新索引整个嵌套文档.对于大型嵌套文档,这可能非常昂贵
  • "交叉引用"嵌套文档是不可能的
  • 最适合不经常更改的数据

父/子

  • 子项与父项分开存储,但路由到同一个分片.因此,父/子在读/查询上的性能略低于嵌套
  • 父/子映射有一点额外的内存开销,因为ES在内存中维护一个"连接"列表
  • 更新子doc不会影响父级或任何其他子级,这可能会在大型文档上节省大量索引
  • 使用父/子进行排序/评分可能很困难,因为Has Child/Has Parent操作有时可能不透明

非规范化

  • 你可以自己管理所有的关系!
  • 最灵活,最大的管理开销
  • 根据您的设置,可能会或多或少地具有高效性

  • 说父母对于查询的性能"略微"不如嵌套可能会产生误导.从我们所看到的情况来看,根据指数大小,它会恶化1-2个数量级. (3认同)
  • 简洁明了地列出了优点和缺点。 (2认同)
  • “非规范化”和“内部对象”有什么区别? (2认同)