elasticsearch:保留冗余(非规范化)数据或保留 id 列表以进行交叉引用?

Posted

技术标签:

【中文标题】elasticsearch:保留冗余(非规范化)数据或保留 id 列表以进行交叉引用?【英文标题】:elasticsearch: Keep redundant (denormalized) data or keep a list of ids for cross-referencing? 【发布时间】:2015-03-09 04:17:24 【问题描述】:

将冗余数据存储在一个索引中更好还是有两个索引然后交叉引用它们更好?即,用户想在电影院看电影。

由于用户有兴趣按影院查找电影,我们可以有一个包含电影nested_type 的影院索引:

// Here, movies field will be a Nested Type, not Object Type.

eclient.index(
    index: 'myindex',
    type: 'theater',
    id: 1,
    body: 
        name: "Grand Cinema",
        description: "Come watch movies!",
        movies: [
           
               title: "Red November",
               description: "A submarine hunt",
               rated: "R",
               score: 10.0
           ,
           
               title: "Cinderbrella",
               description: "A burnt umbrella",
               rated: "PG",
               score: 8.8
           
        ]

    
);

这使得按影院显示电影的简短列表变得很容易,因为影院上的数据是非规范化的。

我们还可以有一个电影索引,其中包含有关电影的更详细信息:

eclient.index(
    index: 'myindex',
    type: 'movie',
    id: 1,
    body: 
        title: "Red November",
        description: "A submarine hunt",
        rated: "R",
        score: 10.0,
        actors: ["Bob", "Alice", "Carol"],
        // other details...
    
);

因此,当用户单击电影以获取更多信息时,我可以查询电影索引并获取其详细信息(即演员)。

如您所见,剧院拥有大量冗余数据。如果电影获得更新的字段,重新索引也会很痛苦。将有两个地方重新索引:影院索引中的电影和电影索引本身。即,电影获得更新的分数。

我想我可以更改它,以便影院索引包含一堆电影 ID,并让电影拥有一堆影院 ID:

// theater index
type: 'theater',
id: 1,
body: 
    name: ...
    description: ...
    movies: [ 1, 2 ]


// movie index
type: 'movie',
id: 1,
body: 
    title: ...
    description: ...
    theaters: [ 1, 2, 3]

但在这种情况下,我如何有效地从影院查询电影信息?我必须获取电影 ID,然后在电影索引上逐一查询它们,以获取一些有限的电影信息以显示在影院页面上。但是,如果某个特定电影的字段发生变化,那么重新索引的工作就会少很多。

哪个是更好的解决方案?我更倾向于认为后者,因为即使电影很少更改其数据,重新索引保存该特定电影的每个影院并重新索引电影索引本身可能会浪费计算能力(瓶颈?)。

第三种解决方案是让影院保存电影 ID,然后只查询 Postgres 数据库中的这些 ID。虽然这可能比通过电影索引单独查询它们要慢?

【问题讨论】:

【参考方案1】:

您正在寻找的是父子关系类型。

在同一索引下,您可以将一种类型定义为另一种类型的父级。 在这种情况下,您可以将所有电影文档保存在电影类型中,将剧院文档保存在剧院类型下。 这种方法的优点是

    您可以根据影院文档的条件搜索电影。例如: ,给我所有在印度影院上映的电影。 链接-http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html 您可以根据电影搜索影院,例如: ,给我所有上映电影“回到未来”的影院。 链接-http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-has-child-query.html

您可以找到更多关于父子的信息here

父子关系相对于嵌套文档的优势

    您可以在不接触影院信息的情况下编辑/更新电影文档。 无需接触电影信息即可添加/删除/编辑影院文档

【讨论】:

谢谢,我完全错过了那部分。他们的页面确实建议谨慎使用父子,因为它往往会占用内存。我想如果它不能很好地与数据一起扩展,那么我可以求助于从数据库中查询 id(我的第三个选择),除非那真的很糟糕? 您应该与父子一起获得下降性能。同样,这些都取决于数据。 警告:孩子只能有一个父母,所以这意味着一部电影不能附加到多个影院,就是这样。 你发现了吗?

以上是关于elasticsearch:保留冗余(非规范化)数据或保留 id 列表以进行交叉引用?的主要内容,如果未能解决你的问题,请参考以下文章

Logstash -> Elasticsearch - 更新非规范化数据

一种循环冗余校验算法,它对具有特定非零值的尾随字节数不变

在高流量网站中进行规范化或非规范化

最强最全面的数仓建设规范指南

最强最全面的数仓建设规范指南

最强最全面的数仓建设规范指南