MongoDB 查询

1. find简介

db.collection.find([query],[fields])

query:查询文档

fields:指定返回的键

micromsg.user集合

{ "_id" : ObjectId("530c90500fd432925cb60204"), "id" : 100, "nickname" : "路人甲01", "lover" : { "id" : 101, "nickname" : "路人甲02" } }
{ "_id" : ObjectId("530c90960fd432925cb60205"), "id" : 101, "nickname" : "路人甲02", "lover" : { "id" : 103, "nickname" : "路人甲03" } }
{ "_id" : ObjectId("530c90970fd432925cb60206"), "id" : 103, "nickname" : "路人甲03", "lover" : { "id" : 100, "nickname" : "路人甲01" } }

 find示例 

db.user.find({"id": 100});
db.user.find({"lover.id": 100}, {"nickname": 1, "lover": 1});
db.user.find({"lover.id": 100}, {"nickname": 1, "lover.nickname": 1});
 注:_id这个键总是被返回,即便没有指定,只能显式剔除。 
db.user.find({"id": 100}, {"nickname": 1, "_id": 0});
 限制:查询文档的值必须是常量,不能引用文档中其他键的值。

2. 查询条件

2.1 关系运算符

$lt, $lte, $gt, $gte, $ne分别对应于<, <=, >, >=, <>,可以组合起来查找一个范围。 

db.user.find({"id": {"$gt": 100, "$lt": 103}})
2.2 $in查询,$nin查询 

与SQL中的in类似,用来查询一个键的多个值。 

db.user.find({"id": {"$in": [100, 101]}});
db.user.find({"id": {"$nin": [100, 101]}});
2.3 逻辑或$or,逻辑非$not 
db.user.find({"$or": [{"id": {"$nin": [100, 101]}}, {"lover.id": 101}]})
db.user.find({"id": {"$not": {"$ne": 100}}});
3.特定于类型的查询 

3.1 null

null不仅仅匹配自身,而且匹配"不存在的"。 

db.user.update({"id": 100}, {"$set": {"age": null}});
db.user.update({"id": 101}, {"$set": {"age": 20}})
//包含了age键不存在的文档
db.user.find({"age": null});
//过滤age键不存在的文档
db.user.find({"age": {"$in": [null], "$exists": true}});
 3.2 正则表达式 

匹配字符串,也可以匹配正则表达式 

db.user.find({"nickname": /^路人甲/});
db.user.update({"id": 100}, {"$set": {"nickname": /^路人甲3/}});
db.user.find({"nickname": /^路人甲3/});
 3.3 数组 

-- 包含 

db.user.update({"id": 100}, {"$set": {"favorite_books": ["西游", "水浒", "三国"]}});
db.user.update({"id": 101}, {"$set": {"favorite_books": ["聊斋", "午夜凶铃", "三国"]}});
db.user.update({"id": 103}, {"$set": {"favorite_books": ["冰与火之歌", "哈利波特"]}});
//包含
db.user.find({"favorite_books": "三国"});
//包含任意一个
db.user.find({"favorite_books": {"$in": ["三国", "水浒"]}});
 -- 包含多个 $all,与顺序无关 
db.user.find({"favorite_books": {"$all": ["三国", "西游"]}});
 -- 完全匹配:完整的数组精确匹配,元素个数和顺序均一致 
//匹配成功
db.user.find({"favorite_books": ["西游", "水浒", "三国"]});
//匹配失败
db.user.find({"favorite_books": ["水浒", "三国"]});
 -- 精确匹配 
db.user.find({"favorite_books.2": "三国"});
 -- $size 
db.user.find({"favorite_books": {"$size": 2}});
 注:"$size"并不能与其他查询子句组合,比如$gt,但是这种查询可以通过在文档中添加一个"size"键的方式来实现。这样每次添加或者移除元素的时候同步更新"size"键,例如 
//添加size键
db.user.update({"id": 100}, {"$set": {"favorite_books_size": 3}});
//更新size键
db.user.update({"id": 100}, {"$push": {"favorite_books": "红楼"}, "$inc": {"favorite_books_size": 1}});
 -- $slice 返回数组的一个子集合 
//1个参数,表示从0开始取n个元素
db.user.find({"id": 100}, {"favorite_books": {"$slice": 2}});
//2个参数,表示从m开始取n个元素
db.user.find({"id": 100}, {"favorite_books": {"$slice": [1, 2]}});
//返回最后一个元素
db.user.find({"id": 100}, {"favorite_books": {"$slice": -1}});
 注:其它键为默认返回。
-- $elemMatch 用来部分指定匹配数组中的单个内嵌文档的限定条件
db.user.update({"id": 100}, {"$set": {"friends": [{"id": 101, "nickname": "路人甲02"}, {"id": 103, "nickname": "路人甲03"}]}});
//错误匹配,两个条件均可满足,但不是同一元素
db.user.find({"friends.id": 101, "friends.nickname": "路人甲03"});
//匹配失败
db.user.find({"friends": {"$elemMatch": {"id": 101, "nickname": "路人甲03"}}});
//匹配成功
db.user.find({"friends": {"$elemMatch": {"id": 101, "nickname": "路人甲02"}}});
 4. $where查询
执行任意JavaScript来进行匹配判断,返回true则匹配成功,返回false则匹配失败。JS中的this为当前文档。例如:文档中的两个值是否相等。
db.classroom.insert({"id": 100, "boys": 50, "girls": 50});
db.classroom.insert({"id": 100, "boys": 51, "girls": 52});

db.classroom.find({"$where": function(){
	return this.boys == this.girls;
}});

db.classroom.find({"$where": "this.boys == this.girls"});
 注:$where执行时,每个文档都要从BSON转换成JavaScript对象,然后通过$where的表达式来运行,不能使用索引,速度要比常规查询慢很多。
5. 游标
数据库使用游标来返回find的执行结果,游标类实现了迭代器接口,可以再forEach循环中使用
var users = db.user.find();
//此时才查询数据库,shell立刻获取前100个结果或前4MB数据(两者之中较小者),作用缓存加速
users.forEach(function(X) {
	print(X.id);
});
 注:当调用find的时候,shell并不立即查询数据库,而是等待真正开始要求获得结果的时候才发送查询,这样在执行之前可以给查询附加额外的选项。
-- limit 限制返回结果的数量
-- skip 忽略前N个匹配的文档
-- 避免使用skip略过大量结果,此时速度会变得很慢,可以通过向文档本身内置查询条件或利用上次的结果计算下一次查询来避免过大的skip
-- sort 排序, 1 升序, -1 降序
 -- 比较顺序
最小值 < null < 数字(整型、长整型、双精度) < 字符串 < 对象/文档 < 二进制数据 < 对象ID < boolean < 日期型 < 时间戳 < 正则表达式 < 最大值
db.user.find().sort({"id": 1}).skip(1).limit(1);
-- count 获取返回结果的数量
db.user.find().count()
6. 高级查询选项
普通查询:只有一个find语句
db.user.find({"id": 100});
包装查询:除了find,还有别的语句
db.user.find({"id": {"$gt": 100}}).sort({"id": 1});
实际查询时,shell会将包装查询组成一个更大的文档
db.user.find({"$query": {"id": {"$gt": 100}}, "$orerby": {"id": 1}});
其它的查询选项
-- $maxscan: integer
指定查询最多扫描的文档数量
-- $min: document
查询的开始条件
-- $max: document
查询的结束条件
-- $hint: document
指定服务器使用哪个索引进行查询
-- $explain: boolean
获取查询执行的细节
-- $snapshot: boolean
确保查询的结果在查询执行那一刻为一致的,不一致只在游标等待结果时集合内容被改变时发生。
7. 游标的销毁
-- 遍历尽了结果以后
-- 客户端发来消息要求终止
-- 游标在客户端已经不在作用域内了,驱动程序会向服务器发送专门的消息
-- 10分钟不使用,数据库游标也会自动销毁,可通过机制告诉数据库不要让游标超时,此时一定要在迭代完结果后将其关闭

你可能感兴趣的:(mongodb)