devise一个MongoDB数据库 – 有很多embedded式文档可以吗?

我正在尝试为简单的投票系统创build一个MongoDB数据库。 如果我要绘制一个模式,那么它看起来像这样:

User { name: String , email: String } Vote { message: String , voters: [ObjectId(User._id)] } 

我有一些关于这个devise的问题,当有一个投票的选民很多:

  1. 将整个选民arrays发送到客户端(更不用说将其caching在内存中)非常昂贵,对吧? 有没有办法以“浅”的方式得到投票,所以当我需要vote.voters时,它会向选民arrays提出另一个数据库请求?
  2. 如果选民已经投了票,我想检查一下,不要数他的票。 要做到这一点,是否有一个查询,我可以运行在embedded式选民arrays快速find这个?
  3. 当显示投票时,我想要显示票数而不需要将选民arrays提交给客户端。 有什么计数查询我可以运行来计算选民的长度?

为了避免你提到的一些潜在的问题,我会在模式中添加一些冗余。 我假设你想1)快速计数的数量和2)确保用户不能投两次。

实现这一目标的一种方法是同时保留用户列表和计票数,并向更新查询添加一个子句,以确保仅当用户的ID不在选民列表中时才添加投票:

 var query = {_id: xyz, voters: {$ne: user_id} var update = {$inc: {votes: 1}, $push: {voters: user_id}} db.votes.update(query, update, true) 

(最后一个参数是upsert ,是Mongo的一个很好的function)

然后,如果要显示投票数,则可以将结果的属性限制为“ votes属性:

 db.votes.find({_id: xyz}, {votes: true}) 

你可以find一个完整的描述或多或less你想在这里做什么: http : //cookbook.mongodb.org/patterns/votes/

1)您只能指定将一个字段子集返回给客户端( docs )。
例如find一个特定的消息,只返回“AnotherField”。

 db.Vote.find({ message : "search for this message" }, { AnotherField : 1 } ); 

2)你可以使用$ addToSet操作符来将一个选民添加到选民arrays( 文档 )哪个(引用):

只有当数组不在数组中时,才会向数组添加值

例如

 { $addToSet : { voters: "Bob"} } 

3)您可以将计数作为额外的字段存储在文档中,然后返回。

希望这可以帮助。