首页 > 代码库 > 【MongoDB】深入了解MongoDB不可不知的十点

【MongoDB】深入了解MongoDB不可不知的十点

一、对象ID的生成

每个mongoDB文档那个都要求有一个主键,它在每个集合中对所有的文档必须是唯一的,主键存放在文档_id字段中。由12个字符组成;

4c291856       238d3b   19b2     000001  

4字节时间戳   机器ID   进程ID  计数器3333

二、BSON

BSONmongodb中用来标示文档的二进制格式,它既是存储格式,也是命令格式。所有文档都以bson存储在磁盘上,所有的查询和命令都用bson文档来指定。

Db.users.find({_id:ObjectId(‘4c291856238d3b19b2000001’)})

Db.users.find({_id:‘4c291856238d3b19b2000001’})

以上两种查询的结果完全不同,其中只有一个能查询到匹配_id字段,这完全取决于users集合中的文档存储的是BSON对象ID还是标示ID十六进制的BSON字符串。

三、聚合命令限制

 在实用性方面,distinct group有一个很大的限制,它们返回的结果集不能超过16M16M的限制并不是这些命令本身所强加的阀值,这是所有的初始查询结果的大小。如果distinctgroup处理不了你的集合结果集,那么就只能使用map-reduce代替了,它的结果可以保存在集合中的非内联返回。

四、原子文档处理

我们知道mongodb不善于处理事物,但要是用户确实需要需要进行查询和更新同时操作怎么办呢? 有一个工具你肯定不想错过,那就是mongodbfindAndModify命令。该命令允许对文档进行原子性更新,并在同一次调用中返回。

db.collections.findAndModify(

{

query:{},update:{},new:true or false 

}

)

默认情况下,findandmodify 命令会返回更新前的文档,要是返回修改后的文档,就把new设置为false. 

五、对数组使用$unset

请注意在单个数组元素上使用$unset的结果可能与你设想的不一样。其结果只是将元素的值设置为null,而非删除整个元素。要想彻底删除某个数组元素,可以用$pull $pop操作符。

六、$addToSet$push的区别

该两者的功能都是给数组添加一个值。但是两者之间有区别,$addToSet要添加的值如果不存在才进行添加操作,但是push只添加一个值;例如:

  tags = [“tools”,”garden”]

如果执行db.collection.update({},{$push:{tag:tools}}) 结果就是 [“tools”,”garden”,“tools”]

如果执行db.collection.update({},{$addToSet:{tag:tools}}) 结果不变

七、稀疏索引创建

在稀疏索引中只会出现被索引键有值的文档,如果想创建稀疏索引,指定{sparse:true}就可以了。例如:

Db.product.ensureIndex({sku:1},{unique:true,sparse:true})

Sku可能存在为null的文档。


八、声明索引时要小心

由于创建索引比较简单,所以很容易在无意间创建索引,如果数据集很大的话,构建会花费很长的时间。并且没办法中种植。同时创建索引时候最好先排序这样更加高效。 

九、用Explaintrue)详细查询执行计划

用户db.collection.find(condition).explain(true)

十、乐观锁

乐观锁就是并发控制,这项技术保证在无需锁定记录的情况下对器进行彻底更新。要理解它,最简单的办法就是想像一个wifi,有多个用户可以同时编辑一个页面。但你肯定不希望用户编辑并更新一个过期的页面,这是就可以使用乐观锁协议,当用户试图保存他们更改的时候,会在更新操作中增加一个时间戳,如果该值比这个页面最近保存的版本旧,就不让用户更新。

这个在mongodb 执行$inc中用到

【MongoDB】深入了解MongoDB不可不知的十点