【问题标题】:Recommended data-structure (for not querying nested data in node.js)推荐的数据结构(用于不查询 node.js 中的嵌套数据)
【发布时间】:2017-08-01 17:44:18
【问题描述】:

Mongo-DB 不支持在嵌套结构中使用通配符进行查询。

在如下所示的数据结构中:

Courses = [{
    'name': 'Learning node.js in 1 day',
    'roles': {
        'team':        { subscribed: [ 'User1' ] },
        'participant': { subscribed: [ 'User1', 'User2' ] },
        'host':        { optional: true, subscribed: [] }
    }
}]

我们需要通配符查找来查找不同角色的订阅者,以免使用这样的查询:

{ $or : [ 
    {"roles.team.subscribed": 'User1'}, 
    {"roles.participant.subscribed": 'User1'}
    {"roles.host.subscribed": 'User1'} 
]}

无论如何,如果我们有一个开放的角色列表,这将不起作用。

如果我们把它改成这样:

'roles':  ['team', 'participant', 'host'],
'subscribed': [ 
    {'user':'User1', 'roles': ['team', 'participant']}, 
    {'user':'User2', 'roles': ['participant']} 
]

同样很难找到课程的所有参与者。无论哪种方式,我们都无法找到用户订阅的所有课程。

我们考虑为订阅创建一个单独的集合(回到关系):

{user_id: 'User1', course_id: '456', role: 'participant'}
{user_id: 'User1', course_id: '456', role: 'team'}
{user_id: 'User2', course_id: '456', role: 'participant'}

什么是最佳实践? 我们希望能够进行所有不同类型的查询,如果它隐藏在嵌套结构中似乎很困难...... 认为这是 mongoDB 中数据结构的一个基本问题。

【问题讨论】:

  • 我确实认为您的结构适合与聚合框架一起使用。但它有一个错误(嗯,让您的查询和 Mongo 的概念变得困难的是根据您的应用程序需求创建您的结构)。角色应该是一个角色数组 [ { "team" : { ... }, "participant" : { ... } }。查询这个结构会更容易。让我考虑一下您当前结构的解决方案。
  • Mongo 也有一些关于从关系转换为非 SQL 的不错的课程,但在你的情况下,这样做不是一个好主意,因为你没有以前的 Sql 结构,所以“回到关系”不是一个好主意。
  • 当你发现自己有这个问题时,我建议你考虑切换到角色名称为字段的模型:{ name: 'team', subscribed: [ 'User1' ], optional: true }

标签: node.js mongodb database


【解决方案1】:

如果你不想改变你的结构,我想我会使用聚合框架来做这样的事情。如果您在角色中的字段不多并且用户无法完全管理,那么我建议您在角色中使用数组并展开它。 让我们来看看你的第一个结构:

Courses = [{
    'name': 'Learning node.js in 1 day',
    'roles': {
        'team':        { subscribed: [ 'User1' ] },
        'participant': { subscribed: [ 'User1', 'User2' ] },
        'host':        { optional: true, subscribed: [] }
    }
}]

这样的项目字段:

名称、角色.团队、角色.参与者、角色.主机

所以你最终会得到这个结构

Courses = [{
    'name': 'Learning node.js in 1 day',
    'roles.team.subscribed': [ 'User1' ] ,
    'roles.participant.subscribed': [ 'User1', 'User2' ] ,
    'roles.host.subscribed': subscribed: [] 
    }
}]

然后你可以展开订阅字段并通过订阅得到一个笛卡尔积,你需要展开3次:

Courses = [
{
    'name': 'Learning node.js in 1 day',
    'roles.team.subscribed.values': 'User1' ,
    'roles.participant.subscribed.values': 'User1',
    'roles.host.subscribed.values': '' 
    }
},
{
    'name': 'Learning node.js in 1 day',
    'roles.team.subscribed.values': 'User1' ,
    'roles.participant.subscribed.values': 'User2',
    'roles.host.subscribed.values': '' 
    }
}

]

最后你可以分别匹配每个角色。

当然你需要使用聚合框架,需要时间来适应它。

【讨论】:

  • 有时很难让它们正常工作,如果您来自 Sql 世界(任何类型的 Sql 数据库),您通常不会考虑如何聚合信息,因为 Sql 使用自己的逻辑解决它。您只需要记住聚合的每个步骤都会减少足够的数据并为您的目标创建更好的子集。
猜你喜欢
  • 2013-08-20
  • 2013-06-25
  • 2014-10-03
  • 2010-11-14
  • 2022-06-10
  • 2012-08-27
  • 1970-01-01
  • 2017-10-10
  • 2016-04-12
相关资源
最近更新 更多