简体   繁体   English

设计MongoDB数据库-可以嵌入许多嵌入式文档吗?

[英]Designing a MongoDB database - are many embedded documents OK?

I'm trying to make a MongoDB database for a simple voting system. 我正在尝试为简单的投票系统创建MongoDB数据库。 If I were to draw a schema, then it looks something like this: 如果要绘制模式,则它看起来像这样:

User {
    name: String
  , email: String
}

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

I have some questions about this design when there are a lot of voters for one vote: 当有很多选民投票时,我对此设计有一些疑问:

  1. Sending the whole voters array to the client's side (not to mention caching it in memory) is very expensive, right? 将整个选民数组发送到客户端(更不用说将其缓存在内存中)非常昂贵,对吗? Is there a way to get the Vote in a "shallow" way, so when I need vote.voters, it will make another database request to the array of voters? 有没有办法以一种“浅”的方式获得投票,所以当我需要vote.voters时,它将向选民名单提出另一个数据库请求?
  2. If a voter has voted already, I want to check that and not count his vote. 如果选民已经投票,我想检查一下,不计算他的投票。 To do that, is there a query I can run in the array of embedded voters to quickly find this? 为此,是否可以在嵌入式投票者数组中运行查询以快速找到该查询?
  3. When showing votes, I'd want to show the number of votes without fetching the voters array to the client side. 在显示投票时,我想显示投票数而不将选民数组提取到客户端。 Is there some kind of count query I can run to count the voters length? 我可以运行某种计数查询来计算选民人数吗?

I would add a bit of redundancy to the schema to avoid some of the potential problems you mention. 我将为架构添加一些冗余,以避免您提到的某些潜在问题。 I assume you want to 1) quickly count the number of votes and 2) make sure a user cannot vote twice. 我假设您要1)快速计算投票数,并2)确保用户不能两次投票。

One way to achieve this is to keep both a list of users and a count of votes, and add a clause to the update query that makes sure that a vote is only added if the user's ID is not in the list of voters: 实现此目的的一种方法是同时保留用户列表和投票计数,并在更新查询中添加一个子句,以确保仅在用户ID不在投票者列表中时才添加投票:

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

(the last parameter is upsert , a very nice feature of Mongo) (最后一个参数是upsert ,这是Mongo的一个很好的功能)

Then, if you want to show the number of votes you can limit the properties of the result to the votes property: 然后,如果要显示投票数,可以将结果的属性限制为votes属性:

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

You can find a complete description of more or less exactly what you want to do here: http://cookbook.mongodb.org/patterns/votes/ 您可以在这里找到有关您想要做的事情的完整描述: http : //cookbook.mongodb.org/patterns/votes/

1) You can specify only to return a subset of fields to the client ( docs ). 1)您只能指定将字段的子集返回给客户端( docs )。
eg to find a specific message and only return "AnotherField". 例如,查找特定消息,仅返回“ AnotherField”。

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

2) You could use the $addToSet operator to add a voter into the voters array ( docs ) which (quote): 2)您可以使用$ addToSet运算符将选民添加到(引用)的选民数组( docs )中:

Adds value to the array only if its not in the array already 仅当值不在数组中时才将其添加到数组中

eg 例如

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

3) You could store the count as an extra field in the document and then just return that. 3)您可以将计数存储为文档中的额外字段,然后将其返回。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM