Mongodb模式设计验证

Mongodb模式设计验证,mongodb,database-schema,nosql,Mongodb,Database Schema,Nosql,我正在开发一个应用程序,允许用户做一些“任务”来赚取积分。“任务”是“活动”的一部分,而“活动”本身就是“品牌”的一部分。我对存储用户响应的模式感到困惑。这就是我建造的。所有任务都有一些活动,用户需要完成这些活动才能完成任务 { _id : ObjectId, user_id : ObjectId, campaign : [ { _id : ObjectId, campaign_id : ObjectId, brand_id :

我正在开发一个应用程序,允许用户做一些“任务”来赚取积分。“任务”是“活动”的一部分,而“活动”本身就是“品牌”的一部分。我对存储用户响应的模式感到困惑。这就是我建造的。所有任务都有一些活动,用户需要完成这些活动才能完成任务

{ _id : ObjectId,
  user_id : ObjectId,
  campaign : [ 
        { _id : ObjectId,
          campaign_id : ObjectId,
          brand_id : ObjectId,
          completed : Boolean,
          points : Number,
          tasks : [
             { _id : ObjectId,
               task_id : ObjectId,
               start_time : Date,
               rewards : points,
               responses : [
                     { _id : ObjectId,
                       activity_id : ObjectId,
                       response : Mixed, 
                    }...]
             }...]
       }...]
}
查询:
1.插入新响应并更新执行给定任务活动的人数。
2.获取用户完成的任务和相应的奖励。
3.获取用户已完成的活动。
4.更新用户对任务的响应。
5.查找所有用户对给定活动的唯一响应

问题:
1.问题是此架构包含嵌套数组,mongodb不允许我在级别1之后使用位置运算符

如果有人能建议一种能更好地执行这些查询的设计,这将是很有帮助的

编辑:

我将上述集合分为两个集合,以方便查询系统,同时保持系统中实体存在的意义

集合1:用户任务(存储用户尝试的活动和任务)

集合2:用户的响应

{ _id : ObjectId,
  user_id : ObjectId,
  task_id : ObjectId,
  rewards : Number,
  responses :[
        { _id : ObjectId,
          activity_id : ObjectId,
          response : Mixed
        } ... ]
}

这使我有了一个更简单的查询系统,特别是在更新和插入响应以及计算特定任务的领导委员会方面。

我将创建专用于任务和响应的集合。它需要您在服务器端编写一些“关系管道”逻辑。这就是使用MongoDB的代价。一些库提供了帮助程序来帮助您完成这项工作(例如Mongoose的
populate
operator)

具有大直径的集合图确实有一些缺点,因为它可能会使查询更加复杂,并且需要在MongoDB客户端和数据库之间进行更多的往返。因此,确实存在使用子文档而不是外国收藏的动机

如何在拥有一个单一集合和太多灯光集合之间找到一个折衷点?这里有一些问题要问你自己:

  • 我是否有超过文档大小限制的风险
  • 在我的信息模型中,父实体是否应该知道子实体,或者在没有子实体的情况下它是否存在并有意义
  • 我是否在客户端构建了一个完整的临时查询/索引引擎来访问子文档

  • 你必须把你的设计颠倒过来。基本上以任务为中心

    数据库中有4个主要集合

  • 使用者
  • 任务
  • 烙印
  • 战役

  • 通过这样做,您将不会遇到扩展问题,同时,您的数据管理将变得轻而易举

    我知道没有一个模式是完全正确或错误的,每个模式都有权衡,但我创建此模式背后的想法是,任务没有标识,除非用户保存对它的响应,而且获取按活动分组的用户任务也变得更容易。唯一的问题是更新特定的响应如果您真的想坚持此模式,您必须在服务器上加载活动,扫描它以查找正确的任务,在该任务中找到响应,更新响应,然后再次保存活动。但是,我再次高度怀疑您关于任务不够重要,无法拥有自己的集合的说法,并且随着您改进应用程序,情况只会变得更糟:)。是的。我想我现在看到了。您认为为响应创建一个新集合并保留模式的其余部分有意义吗?这样,我就不必打破活动和任务的层次结构,并且仍然可以指示性地更新和分析响应。我对这种方法不太乐观,但没有什么可以阻止您将其作为迁移的第一步。我将编辑我的答案,以帮助您对此进行解释。我同意瓦伦丁的观点。恕我直言,如果您在子文档中有_id,或者如果您的查询远比典型的SQL查询复杂,那么您就大错特错了。如果它有一个id,它需要一个集合,句号。还要记住,对象有所有者,并发写入必须是原子的。这将在查询中移动越来越多的逻辑,然后您将陷入SQL混乱。我想了解更多关于用例的信息。什么是对任务的响应?完成一项任务或一项活动到底意味着什么?回答与完成有什么关系?任务是一个问题或一系列问题,它们是系统中的活动。完成所有活动即完成一项任务,完成活动中的所有任务即完成一项活动。以任务为中心会让用户很难获得所有信息,这就是应用程序的工作方式。您可以在任务中获得品牌和活动的相关信息,如品牌id、公司id和助理id(这是用户)-那么,获得每个不同场景的任务将非常容易。
    { _id : ObjectId,
      user_id : ObjectId,
      task_id : ObjectId,
      rewards : Number,
      responses :[
            { _id : ObjectId,
              activity_id : ObjectId,
              response : Mixed
            } ... ]
    }