Mongodb 查询(1)2011-12-12 10:531.find方法介绍
在不传入参数的情况下,find方法缺省使用{}做参数,它匹配所有的document。
我们可以传入一个查询document给find方法来限制输出,如:查找年龄为27的用户
> db.users.find({"age" : 27})
一个查询document里可以包括多个条件,如:查询年龄为27并且名字叫joe的用户
> db.users.find({"username" : "joe", "age" : 27})
条件之间都是And关系。
指定查询返回的内容
有时候我们并不需要返回document里所有的key/value对,我们可以给find(或findOne)方法传入第二个参数来指定返回哪些key的值。
比如:我们只想要用户的名字和Email
> db.users.find({}, {"username" : 1, "email" : 1})
{
"_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
"username" : "joe",
"email" : "
[email protected]"
}
"_id"键总是会被返回。
如果想指定不想返回的key,如:返回除了fatal_weakness以外的key的值
> db.users.find({}, {"fatal_weakness" : 0})
用这个方法可以把缺省返回的"_id"给排除掉
> db.users.find({}, {"username" : 1, "_id" : 0})
{
"username" : "joe",
}
限制
查询document里边key的值对数据库来说必须是个常量,假如collection里边有两个key,一个叫int_stock一个叫num_sold,
如果我们想查询这两个key相等的document,下边的查询是行不通的
> db.stock.find({"in_stock" : "this.num_sold"}) // doesn't work
2.查询条件
"$lt", "$lte", "$gt", 和"$gte"分别对应<,<=,>,>=
“$ne" 不等于
"$in"和sqlserver的in差不多意思
"$nin”就是not in了
"$or" 是多字段间的条件关联与sqlserver的or 一样
如:查询年龄在18到30之间的用户
> db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})
“$ne" 不等于,可以用于任意类型的数据
如,查找名字不叫joe的用户
> db.users.find({"username" : {"$ne" : "joe"}})
OR查询
mongoDB里有两种使用OR的方法,如果是一个key对应的多个值,可以用"$in",还有个”or"是一种更通用的方法。
如:我们在进行一个抽奖活动,ticket No是725,542,390的三个中奖了,我们可以这样把这三个document查出来
> db.raffle.find({"ticket_no" : {"$in" : [725, 542, 390]}})
"$in"里边指定的值可以是不同的数据类型
与"$in"相反的操作就是"$nin”,返回指定的key的值不存在于数组里边的document,
> db.raffle.find({"ticket_no" : {"$nin" : [725, 542, 390]}})
上边的查询返回没中奖的所有ticket。
如果要在多个key的查询条件之间建立Or关系就得用"$or",如,查询彩票号码为725, 542, 390 或者winner为true的document
> db.raffle.find({"$or" : [{"ticket_no" : {"$in" : [725, 542, 390]}},{"winner" : true}]})
$not
"$not"可以应用于上边说的所有的条件操作符上,举个例子之前我们先看下求余(取模)操作符"$mod","$mod"指定一个整数数组做为key的值,
里边两个数字,第一个是对其求余的数字,第二个是余数。比如,我们要找id_num的值对5求余,余数为1的document
> db.users.find({"id_num" : {"$mod" : [5, 1]}})
现在我们使用$not,如果找id_num对5求余后余数不为1的document
> db.users.find({"id_num" : {"$not" : {"$mod" : [5, 1]}}})
规律
回头再看下前一章的更新修饰符,就会发现同样是$打头的符号,它和本章说的查询条件符号的位置是不一样的,
在查询里,"$lt"属于内层document,而更新的时候"$inc"是外层document的key。
一个key上可以有多个查询条件,却不能有多个更新。
查询年龄为20到30的用户可以这样做
> db.users.find({"age" : {"$lt" : 30, "$gt" : 20}})
但是却没有下边这种更新修饰符
{"$inc" : {"age" : 1}, "$set" : {age : 40}}
3.特殊类型查询
null
null同时匹配自身和不存在的key,
> db.c.find()
{ "_id" : ObjectId("4ba0f0dfd22aa494fd523621"), "y" : null }
{ "_id" : ObjectId("4ba0f0dfd22aa494fd523622"), "y" : 1 }
{ "_id" : ObjectId("4ba0f148d22aa494fd523623"), "y" : 2 }
如果要查找y为null的document
> db.c.find({"y" : null})
{ "_id" : ObjectId("4ba0f0dfd22aa494fd523621"), "y" : null }
查找key为null的document时,缺少此key的所有document也会返回
> db.c.find({"z" : null})
{ "_id" : ObjectId("4ba0f0dfd22aa494fd523621"), "y" : null }
{ "_id" : ObjectId("4ba0f0dfd22aa494fd523622"), "y" : 1 }
{ "_id" : ObjectId("4ba0f148d22aa494fd523623"), "y" : 2 }
如果想查找key存在并且为null的document,就要用"$exists"符号,
> db.c.find({"z" : {"$in" : [null], "$exists" : true}})
这个办法看起来比较笨,没办法,我们没有"$eq"条件符号。
正则表达式
查找名字叫joe,但是忽略大小写的document
> db.users.find({"name" : /joe/i})
mongoDB使用Perl Compatible Regular Expression (PCRE)来匹配正则表达式,所有PCRE允许的语法都可以在mongoDB里使用。
查询数组
查询数组很简单,通常情况下,数组的每个元素的值都能看作key的值。
例如,我们有一些水果
> db.food.insert({"fruit" : ["apple", "banana", "peach"]})
我们查找水果里有香蕉的ducoment
> db.food.find({"fruit" : "banana"})
用起来就好像我们有这么一个document在
{"fruit" : "apple","fruit" : "banana", "fruit" : "peach"}
当然,上边这个document是不合法的。
$all
如果要匹配数组里的多个元素,就要用“$all”。
例如,我们有这样一个collection
> db.food.insert({"_id" : 1, "fruit" : ["apple", "banana", "peach"]})
> db.food.insert({"_id" : 2, "fruit" : ["apple", "kumquat", "orange"]})
> db.food.insert({"_id" : 3, "fruit" : ["cherry", "banana", "apple"]})
要查询既有apple又有banana的document
> db.food.find({fruit : {$all : ["apple", "banana"]}})
{"_id" : 1, "fruit" : ["apple", "banana", "peach"]}
{"_id" : 3, "fruit" : ["cherry", "banana", "apple"]}
$all的值里边的元素是没有顺序的,只要目标包含里边的每个元素即可,如果不使用$all,就会执行精确的匹配检查。
> db.food.find({"fruit" : ["apple", "banana", "peach"]})
上边这个查询会匹配第一个document
> db.food.find({"fruit" : ["apple", "banana"]})
这个查询就不会匹配第一个document
> db.food.find({"fruit" : ["banana", "apple", "peach"]})
同样,这个查询也不会匹配第一个document
如果要匹配数组里指定的元素,就要使用key.index这种语法
> db.food.find({"fruit.2" : "peach"})
index 是从0开始索引的
$size
按照数组中元素的个数查询
> db.food.find({"fruit" : {"$size" : 3}})
$size 不能和比较条件符号(如$gt)联合使用
$slice操作符
上边曾经提到过,使用find方法的第二个参数,指定哪些键值会被返回,$slice操作符可以返回数组元素的一个子集。
例如,查找博客和它的前10条评论
> db.blog.posts.findOne(criteria, {"comments" : {"$slice" : 10}})
或者,如果想要后10条评论的话
> db.blog.posts.findOne(criteria, {"comments" : {"$slice" : -10}})
也可以返回中间的一段结果
> db.blog.posts.findOne(criteria, {"comments" : {"$slice" : [23, 10]}})
上边的查询跳过前23个元素,返回第24个到第34个元素。
本文转载百度空间博客
rosurfer
http://hi.baidu.com/prosurfer/blog/item/07a8037be83464ea0ad187fc.html