设计一个MongoDB数据库 - 很多嵌入式文件可以吗?

时间:2011-03-15 07:59:41

标签: javascript node.js mongodb database

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

User {
    name: String
  , email: String
}

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

当有很多选民投票时,我对这个设计有一些疑问:

  1. 将整个选民阵列发送到客户端(更不用说将其缓存在内存中)非常昂贵,对吧?有没有办法以“浅薄”的方式进行投票,所以当我需要vote.voters时,它会向选民阵列提出另一个数据库请求?
  2. 如果选民已经投票,我想检查一下并且不计算他的投票。要做到这一点,我是否可以在嵌入式选民阵列中运行查询以快速找到它?
  3. 在显示投票时,我想显示的投票数,而将选民阵列提取到客户端。是否有某种计数查询我可以运行以计算选民的长度?

2 个答案:

答案 0 :(得分:1)

我会在架构中添加一些冗余,以避免您提到的一些潜在问题。我假设你想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的一个非常好的功能)

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

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

您可以在此处找到或多或少的完整描述:http://cookbook.mongodb.org/patterns/votes/

答案 1 :(得分:0)

1)您只能指定将字段子集返回给客户端(docs) 例如查找特定消息并仅返回“AnotherField”。

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

2)您可以使用$ addToSet运算符将选民添加到选民阵列(docs)中(引用):

  

仅在数组中添加值   已不在数组中

e.g。

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

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

希望这有帮助。