查找文档
筛选查找
db.collection.find();
- 返回一个集合中文档的子集,子集的 范围从 0 个文档到整个集合;
db.collection.findOne();
- 返回筛选的一个文档;
指定返回键
- 设置第二参数,在第一参数筛选后的文档中只返回第二参数设置的键值;默认包含
_id
- 也可以在第二参数中设置
_id: 0
去掉_id
;
//返回name,age,_id
db.test.find({}, {name: 1, age: 1});
//去掉_id
db.test.find({}, {name: 1, age: 1, _id: 0});
查询条件
$lt : <
;$lte: <=
;$gt: >
;$gte: >=
;$ne: !=
;
db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
OR查询
- 使用
$in
来查询一个键匹配的多个值; - 使用
$nin
来查询一个键不匹配的多个值; - 使用
$or
查询多个键中查询任意的给定值; - 使用
$and
查询多个键中同时匹配的给定值; - 使用
$not
: 取反,可以用在任何其他条件之上;
db.users.find({"user_id" : {"$in" : [12345, "joe"]})
//
db.raffle.find({"ticket_no" : {"$nin" : [725, 542, 390]}})
//查询ticket_no=725或winner=true的元素;
db.raffle.find({"$or" : [{"ticket_no" : 725}, {"winner" : true}]})
//
db.users.find({"$and" : [{"x" : {"$lt" : 1}}, {"x" : 4}]})
//
db.raffle.find({"ticket_no" : {"$not": {"$nin" : [725, 542, 390]}}})
特定数值查询
$mod
: 取模运算,查询的值除以第一个给定值,若余数等于第二个给定值则匹配成功;
db.users.find({"id_num" : {"$mod" : [5, 1]}})
条件语句
- 条件语句是内层文档的键,而修改器则是外层文档的键;
- 一个键可以有任意多个条件,但是一个键不能对应多个更新修改器;
- 有一些“元操作符”(meta-operator)也位于外层文档中,比如
$and
,$or
和$nor
;
查询特定类型
- null: 直接查询还会匹配不包含这个键的文档,可以通过
$exists
条件判定键值已存在;
db.c.find({"z" : {"$in" : [null], "$exists" : true}})
- 正则表达式:MongoDB 使用 Perl 兼容的正则表达式(PCRE)库来匹配正则表达式;
db.users.find({"name" : /joey?/i})
查询数组: 与查询标量值是一样的;
$all
:与$in
不同,查询一个键同时匹配的多个值;- 查询数组特定位置的元素,需使用 key.index 语法指定下标;
$size
: 查询特定长度的数组;并不能与其他查询条件组合使用,但是这种查询可以通过在文档中添加一个size
键的方式来实现;每一次向指定数组添加元素时,同时增加size
的值;$slice
: 指定find
的第二个参数,指定需要返回的键;表示特定的范围;- 在不知道元素下标时希望返回与查询条件 相匹配的任意一个数组元素,使用
$
操作符得到一个匹配的元素;
* 使用$elemMath
同时使用查询条件中的两个语句与 一个数组元素进行比较;但不会匹配非数组元素; - 可以使用
min()
和max()
将查询条件遍历的索引范围限制为$gt
和$lt
的值;在可能包含数组的文档上应用范围查询时使用更好;
db.foot.find({"fruit" : {"$all" : ["apple", "banana"]});
//
db.food.find({"fruit" : {"$size" : 3}});
//返回博客评论的后10条;
db.blog.posts.findOne(criteria, {"comments" : {"$slice" : -10}})
//返回24~33的元素;
db.blog.posts.findOne(criteria, {"comments" : {"$slice" : [23, 10]}})
//
db.blog.posts.find({"comments.name" : "bob"}, {"comments.$" : 1});
//
db.test.find({"x" : {"$elemMatch" : {"$gt" : 10, "$lt" : 20}});
//
db.test.find({"x" : {"$gt" : 10, "$lt" : 20}).min({"x" : 10}).max({"x" : 20});
- 查询内嵌文档:可以使用点表示法查询内嵌文档的键:
db.people.find({"name.first" : "Joe", "name.last" : "Schmoe"})
$where
查询
- 当使用键 / 值方式无法满足时,可以使用
$where
,可以在查询中执行任意的JavaScript
; - 不是非常必要时,一定要避免使用
$where
查询,因为它们在速度上要比常规 查询慢很多; - 每个文档都要从
BSON
转换成JavaScript
对象,然后通过$where
表达式来运行;
//返回两个键具有相同值的文档
db.foo.find({"$where" : function () {
for (var current in this) {
for (var other in this) {
if(current != other && this[current] == this[other]) {
return true;
}
}
}
return false;
}});
- 可以在运行
mongod
时指定--noscripting
选项,完全关闭JavaScript
的执行;
游标
- 可以限制结果的数量,略过部分结果,根据任意键按任意顺序的 组合对结果进行各种排序,或者是执行其他一些强大的操作;
调用
find
时,shell
并不立即查询数据库,而是等待真正开始要求获得结果时才发 送查询,这样在执行之前可以给查询附加额外的选项;hasNext, next
方法
var cursor = db.collection.find();
while (cursor.hasNext()) {
obj = cursor.next();
// do stuff
}
limit,skip
方法
- 避免使用skip略过大量结果,因为先查找后过滤;
- 不用skip对结果分页;
- 不用skip随机选取文档;最好的方法是插入文档时给每个文档都添加一个额外的随机键;
//指定限制个数上限
db.c.find().limit(3);
//跳过最先匹配的3个
db.c.find().skip(3);
sort
:
- 接受一组键 / 值对,键对应文档的键名,值代表排序的方向。
- 排序方向1(升序)或者 ?1(降序)。
- 如果指定了多个键, 则按照这些键被指定的顺序逐个排序。
//按照username升序及age降序排序
db.c.find().sort({username : 1, age : -1})
//分页
var page1 = db.foo.find().sort({"date" : -1}).limit(100);
var latest = null;
// 显示第一页
while (page1.hasNext()) {
latest = page1.next();
display(latest);
}
// 获取下一页
var page2 = db.foo.find({"date" : {"$gt" : latest.date}}); page2.sort({"date" : -1}).limit(100);
比较顺序:
- 排序顺序是预先定义好的。优先级从小到大,其顺序如下:
(1) 最小值;
(2) null;
(3) 数字(整型、长整型、双精度); (4) 字符串;
(5)对象/文档;
(6) 数组;
(7) 二进制数据;
(8) 对象 ID;
(9) 布尔型;
(10) 日期型;
(11) 时间戳;
(12) 正则表达式;
(13) 最大值 。