MongoDB学习 (六):查询
本文地址:http://www.iyunv.com/egger/archive/2013/06/14/3135847.html欢迎转载 ,请保留此链接๑·́ ₃·̀๑!本文将介绍操作符的使用,配合操作符,我们可以执行更加复杂的操作。
目录
[*]
查询操作
[*]集合查询方法 find()
[*]查询内嵌文档
[*]查询操作符(内含 数组查询)
[*]"$gt" 、"$gte"、 "$lt"、 "$lte"、"null查询"、"$all"、"$size"、"$in"、"$nin"、
[*]"$and"、"$nor"、"$not"、"$or"、"$exists"、"$mod"、"$regex"、"$where"、"$slice"、"$elemMatch"
1.1 集合查询方法 find()
db.collection.find()查询集合中文档并返回结果为游标的文档集合。
语法:db.collection.find(query, projection)
参数 类型 描述
query 文档 可选. 使用查询操作符指定查询条件
projection 文档 可选.使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略).
返回值: 匹配查询条件的文档集合的游标. 如果指定投影参数,查询出的文档返回指定的键 ,"_id"键也可以从集合中移除掉。
注意:在mongo shell中我们不需要JavaScript游标处理方法就可以直接访问作为查询结果的文档集合。mongo shell默认返回游标中的前20条文档。当执行查询操作时,mongo shell直接自动的对游标执行迭代操作并显示前20条文档。输入"it"显示接下来的20条文档。
find的第一个参数是查询条件,其形式也是一个文档,决定了要返回哪些文档,空的査询文档{}会匹配集合的全部内容。要是不指定査询文档,默认就是{},如同SQL中"SELECT * FROM TABLENAME"语句。
//将返回集合中所有文档
db.collection.find()
//或者
db.collection.find({})
第一个参数若为键/值对时,查询过程中就意味着执行了条件筛选,就如同我们使用Linq查询数据库一样。下面查询操作将返回user集合中age键值为16的文档集合。
//mongo db
db.user.find({age:16})
//Linq to sql
dbContext.user.select(p=>p.age==16)
上面的查询默认执行“==”操作(就如同linq中 p.age==16),文档中若存在相同键的值和查询文档中键的值相等的话,就会返回该文档。
第一个参数若包含多个键/值对(逗号分隔),则相当于查询AND组合条件,“条件1 AND条件2 AND…AND 条件N".例如查询年龄为28且性别为男性的文档集合:
//mongo db
db.user.find({age:28,sex:"male"})
//Linq to sql
dbContext.user.select(p=>p.age==28&&p.sex=="male")
//SQL
SELECT * FROM user WHERE age=28 AND sex="male"
指定返回的键
我们可以通过find 的第二个参数来指定返回的键。
若find不指定第二个参数,查询操作默认返回查询文档中所有键值。像SQL中我们可以指定查询返回字段一样 ,mongo中也可以指定返回的键,这样我们就可以避免查询无用键值查询所消耗的资源、会节省传输的数据量和内存消耗。
集合user包含 _id,name,age,sex,email等键,如果查询结果想只显示集合中的"name"和"age"键,可以使用如下查询返回这些键,。
> db.users.find({}, {"name" : 1, "age" : 1})
上面查询结果中,"_id"这个键总是被返回,即便是没有指定也一样。但是我们可以显示的将其从查询结果中移除掉。
> db.users.find({}, {"name" : 1, "age" : 1, "_id":0})
在第二个参数中,指定键名且值为1或者true则是查询结果中显示的键;若值为0或者false,则为不显示键。文档中的键若在参数中没有指定,查询结果中将不会显示(_id例外)。这样我们就可以灵活显示声明来指定返回的键。
我们在使用RDMS时,有时会对表中多个字段之间进行比较。如表store中,有销售数量soldnum和库存数量stocknum两个字段,我们要查询表中销售数量等于库存数量的记录时可以使用下面的sql语句:
SELECT * FROM store WHERE soldnum=stocknum
那么换成mongodb呢,使用find()能实现类似的功能吗?
> db.store.find ({ "soldnum" : "stocknum"})
//或者
> db.store.find ({ "stocknum":"soldnum" })
结果是不行的!!我们可以使用$where运算符来进行相应的操作。
1.2查询内嵌文档
查询文档有两种方式,一种是完全匹查询,另一种是针对键/值对查询。
> db.profile.find()
{ "_id" : ObjectId("51d7b0d436332e1a5f7299d6"), "name" : { "first" : Barack", "last" : "Obama" } }
>
内嵌文档的完全匹配查询和数组的完全匹配查询一样,内嵌文档内键值对的数量,顺序都必须一致才会匹配:
> db.profile.find({ name : { first : "Barack", last : "Obama" } });
{ "_id" : ObjectId("51d7b0d436332e1a5f7299d6"), "name" : { "first" : Barack", "last" : "Obama" } }
>
//无任何返回值
> db.profile.find({ name : {last : "Obama" , first : "Barack"} });
>
推荐采用针对键/值对查询,通过点表示法来精确表示内嵌文档的键:
//查询结果一样
db.profile.find({"name.first" : "Barack" , "name.last" : "Obama"});
//或者
db.profile.find({"name.last" : "Obama" , "name.first" : "Barack"} );
运行结果:
査询文档可以包含点,来表达“深入内嵌文档内部”的意思,点表示法也是待插入的文档不能包含的原因。当内嵌文档变得复杂后,如键的值为内嵌文档的数组,内嵌文档的匹配需要些许技巧,例如使用$elemMatch操作符。
集合blogs有如下文档:
{
"content" : ".....",
"comment" : [
{
"author" : "zhangsan",
"score" : 3,
"comment" : "shafa!"
},
{
"author" : "lisi",
"score" : 5,
"comment" : "lzsb!"
}
]
}
我们想查询评论中用户“zhangsan”是否有评分超过4分的评论内容,但我们利用“点表示法”直接写是有问题的,这条查询条件和数组中不同的文档进行了匹配!
> db.blogs.find({"comment.author":"zhangsan", "comment.score":{"$gte":4}});
上面的结果不是我们期望的,下面使用“$elemMatch”操作符即可将一组条件限定到数组中单条文档的匹配上:
> db.blogs.find({"comment":{"$elemMatch":{"author":"zhangsan","score":{"$gt":4}}}});
> db.blogs.find({"comment":{"$elemMatch":{"author":"zhangsan","score":{"$gt":2}}}});
1.3 查询操作符
下面我们将配合查询操作符来执行复杂的查询操作,比如元素查询、 逻辑查询 、比较查询操作。
我们使用下面的比较操作符"$gt" 、"$gte"、 "$lt"、 "$lte"(分别对应">"、 ">=" 、"
页:
[1]