Fork me on GitHub

MongoDB学习笔记

1、$where查询

  不是非常必要时,一定要避免使用“$where”查询,因为它们在速度上要比常规查询慢很多。每个文档要从BSON转换成Javascript对象,然后通过“$where”的表达式来运行。同样还不能利用索引。所以,只在走投无路时才考虑“$where”这种用法。
  将常规查询作为前置过滤,与“$where”组合使用可以不牺牲性能。如果可能的话,用索引根据非“$where”子句进行过滤,“$where”只用于对结果进行调优。

2、游标
  数据库使用游标来返回find的执行结果,客户端对游标的实现通常能够对最终结果进行有效的控制。可以限制结果的数量,略过部分结果,根据任意方向任意键的组合对结果进行各种排序,或者是执行其他一些功能强大的操作。
  要想从shell中创建一个游标,首先要对集合填充一些文档,然后对其执行查询,并将结果分配给一个局部变量(用var声明的变量就是局部变量)。要迭代结果,可以使用游标的next方法,也可以使用hasNext来查看有没有其他结果。例如:

1
2
3
4
5
> var cursor = db.collection.find();
> while (cursor.hasNext()){
obj = cursor.next();
// do stuff
}

3、索引
建立索引的方法:

1
2
3
4
db.people.ensureIndex({"username":1}) #以username为索引
db.people.ensureIndex({"date":1,"username":1}) #以date,username为索引
db.people.ensureIndex({"comments.date":1}) #索引内嵌文档中的键和普通的键创建索引没有什么区别
db.people.ensureIndex({"username":1},{"background":true}) #建立索引既耗时也费力,还需要消耗很多资源。使用{"background":true}选项可以使这个过程在后台完成,同时正常处理请求

建立索引时要考虑如下问题:

  • 会做什么样的查询?其中哪些键需要索引?
  • 每个键的索引方向是怎样的?
  • 如何应对扩展?有没有种不同的键的排列可以使常用数据更多地保留在内存中?
    要是能回答这些问题,说明你已经做好了索引的准备了。

创建索引的缺点就是每次插入、更新和删除时都会产生额外的开销。这是因为数据库不但需要执行这些操作,还要将这些操作在集合的索引中标记。因此,要尽可能少创建索引。每个集合默认的最大索引个数为64个。

注意:一定不要索引每一个键。这会导致插入非常慢,还会占用很多空间,并且很可能对查询速度提升不大。

MongoDB排序需要将所有数据提取到内存来排序,因此,可以做无索引排序是有个上限的,那就是不可能在内存里面做T级别数据的排序。一旦集合大到不能在内存中排序,MongoDB就会报错。

索引管理:索引的元信息存储在每个数据库的system.indexes集合中。这是一个保留集合,不能对其插入或者删除文档。操作只能通过ensureIndex或者dropIndexes进行。
建立索引既耗时也费力,还需要消耗很多资源。使用{“background”:true}选项可以使这个过程在后台完成,同时正常处理请求。

MongoDB支持动态建立普通集合,还支持固定集合(要实现创建,而且大小固定。如果固定集合空间不足,最早的文档就会被删除,为新的文档腾出空间,这意味着固定集合在新文档插入的时候自动淘汰最早的文档。

固定集合和普通集合还有一个区别,就是在默认情况下固定集合没有索引,即便是“_id”上也没有索引。

固定集合有种特殊的排序方式,叫做“自然排序”。自然排序就是文档在磁盘上的顺序顺时针方向依次的。文档总数安装插入的顺序存储的,自然顺序就是与此相同的。也可以使用自然排序按照反向插入的顺序查询。

尾部游标只能在固定集合上使用。

-------------本文结束感谢您的阅读-------------

本文标题:MongoDB学习笔记

文章作者:ElwinHe

发布时间:2017年10月08日 - 12:10

最后更新:2018年01月08日 - 22:01

原始链接:http://www.elwinhe.xyz/blog/a36562d7.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。