atomically {
if( exists a document with username='jane' ) {
print "username already in use please choose another";
} else {
insert a document with username='jane' in the users collection;
print("thanks you have registered as user jane.");
}
}
这里的关键是原子操作的范围/ACID内容就是这个文档。这样的话我们就需要保证所有在原子操作中涉及的字段都属于同一个文档。 索引
Mongodb支持声明索引。mongodb中的索引同关系型数据库中的索引非常类似:它们为高效查询而设计,必须显式声明。这样的话,作为模式设计的一部分,我们需要考虑定义那些索引。同关系型数据库一样,索引可以随后再增加 - 如果我们决定将来会增加新的索引,我们可以随后再加。 分片
另外一个在模式设计时需要考虑的就是分片了。一个BSON文档(它可能有一些重要内嵌字段)仅会驻留在一个分片上面。
一个集合可以被分片。当被分片,这个集合会有一个分片关键字,它决定该集合如何分片到集群中。
通常(不是必须)对分片集合的查询会包含分片关键字。
需要注意的是,分片后再更改分片关键字非常困难。 例子
让我们来考虑一个内容管理系统的例子。下面的例子我们使用的mongo shell语法,但是它应该也可以在任何编程语言中实现 - 只要使用合适的驱动就可以了。
我们的内容管理系统会保存博客。博客有作者。我们还要支持对博客进行评论和投票。我们还希望增加标签来提供搜索功能。
一个好的模式设计可能会使用两个mongodb集合,一个叫做posts,另一个叫users.这就是我们的例子中要使用的。
我们的用户有一些属性 - 注册时使用的用户ID,名称,和他们的karma。例如我们可以:
> db.posts.findOne()
{
_id : ObjectId("4e77bb3b8a3e000000004f7a"),
when : Date("2011-09-19T02:10:11.3Z",
author : "alex",
title : "No Free Lunch",
text : "This is the text of the post. It could be very long.",
tags : [ "business", "ramblings" ],
votes : 5,
voters : [ "jane", "joe", "spencer", "phyllis", "li" ],
comments : [
{ who : "jane", when : Date("2011-09-19T04:00:10.112Z"),
comment : "I agree." },
{ who : "meghan", when : Date("2011-09-20T14:36:06.958Z"),
comment : "You must be joking. etc etc ..." }
]
}
对比一下在关系型数据中如何实现这种模式,你会发现很有趣。我们会首先有一个用户集合和博客集合。但是通常还需要增加标签集合,投票集合,和评论集合。收集一篇博客的全部信息可能会有些麻烦。
这里获取一个完整博客信息,我们可以:
> // make and index of all tags so that the query is fast:
> db.posts.ensureIndex( { tags : 1 } )
> db.posts.find( { tags : "business" } )
查询meghan所有的评论: