nosilence 发表于 2015-7-5 13:29:08

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]
查看完整版本: MongoDB学习 (六):查询