我使用mongodb存储多个网站的分析。这些网站每天有数百万次访问,每天有数千个不同的网址。我要计算每个网址的访问次数。
现在我每天都需要获取前一天的数据。
将每个网址存储在其自己的文档或一个文档中的一个对象下的所有网址是否更好?
答案 0 :(得分:1)
包含大型对象的多个文档或更少文档
不可避免地,使用MongoDB的每个人都必须在使用带有id引用或嵌入文档的多个集合之间进行选择。两种解决方案都有其优点和缺点。学习使用两者:
使用单独的收藏品
db.posts.find();
{_id: 1, title: 'unicorns are awesome', ...}
db.comments.find();
{_id: 1, post_id: 1, title: 'i agree', ...}
{_id: 2, post_id: 1, title: 'they kill vampires too!', ...}
使用嵌入式文档
db.posts.find();
{_id: 1, title: 'unicorns are awesome', ..., comments: [
{title: 'i agree', ...},
{title: 'they kill vampires too!', ...}
]}
单独的集合提供最大的查询灵活性
// sort comments however you want
db.comments.find({post_id: 3}).sort({votes: -1}).limit(5)
// pull out one or more specific comment(s)
db.comments.find({post_id: 3, user: 'leto'})
// get all of a user's comments joining the posts to get the title
var comments = db.comments.find({user: 'leto'}, {post_id: true})
var postIds = comments.map(function(c) { return c.post_id; });
db.posts.find({_id: {$in: postIds}}, {title: true});
选择嵌入式文档的范围更为有限
// you can select a range (useful for paging)
// but can't sort, so you are limited to the insertion order
db.posts.find({_id: 3}, {comments: {$slice: [0, 5]}})
// you can select the post without any comments also
db.posts.find({_id: 54}, {comments: -1})
// you can't use the update's position operator ($) for field selections
db.posts.find({'comments.user': 'leto'}, {title: 1, 'comments.$': 1})
文档(包括其所有嵌入文档和数组)不能超过16MB。
单独的收藏需要更多工作
// finding a post + its comments is two queries and requires extra work
// in your code to make it all pretty (or your ODM might do it for you)
db.posts.find({_id: 9001});
db.comments.find({post_id: 9001})
嵌入式文档简单快捷(单一搜索)
// finding a post + its comments
db.posts.find({_id: 9001});
插入和更新没有太大差异
// separate collection insert and update
db.comments.insert({post_id: 43, title: 'i hate unicrons', user: 'dracula'});
db.comments.update({_id: 4949}, {$set : {title: 'i hate unicorns'}});
// embedded document insert and update
db.posts.update({_id: 43}, {$push: {title: 'lol @ emo vampire', user: 'paul'}})
// this specific update requires that we store an _id with each comment
db.posts.update( {'comments._id': 4949}, {$inc:{'comments.$.votes':1}})
因此,如果您需要选择单个文档,需要对查询进行更多控制或拥有大量文档,则单独的集合是很好的。当您需要整个文档,包含$ cut评论的文档或根本没有评论时,嵌入式文档是很好的。作为一般规则,如果您有很多“评论”或者它们很大,那么单独的集合可能是最好的。较小和/或较少的文档往往适合嵌入。
记住,你总能改变主意。尝试两者是最好的学习方式。