现在的位置: 首页 > 综合 > 正文

4.MongoDB的查询

2014年02月26日 ⁄ 综合 ⁄ 共 5345字 ⁄ 字号 评论关闭

写在前面

在前面几篇中介绍过,MongoDB中的查询呢》是用find(  )来进行查找数据的。即是: db.user.find(  ) 。那么这一篇主要针对find(  )做详细的深入。

  1. 使用find和findOne函数和查询条件来查询对应的数据。
  2. 使用$ 条件来查询实现范围、集合包含、不等式和其他查询。
  3. 使用 $where 字句

1.find( )和findOne( )

在MongoDB中查询用find( )就可以对数据进行查询。findOne( )是查询最近的一个文档。当然里面也可以带参数,这样查询就更有针对性了。

Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

C:\Documents and Settings\Administrator>E:

E:\>CD MongoDB

E:\MongoDB>mongo.exe
MongoDB shell version: 2.0.2
connecting to: test
> use php  //使用php库
switched to db php
> db.blog.find() //使用find( )在blog集合中查找所有的文档,查询结果如下。
{ "_id" : ObjectId("4f0bc1245a5904bae2b767a8"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z") }
{ "_id" : ObjectId("4f0bc11d5a5904bae2b767a7"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z"), "comments" : "hao a
 hao a " }
{ "_id" : ObjectId("4f0cf96bbc8c53013bb90682"), "title" : "okokok", "content" :
"123456", "time" : "2011023023", "comments" : "23224" }
> db.blog.findOne()  //使用findOne( )查找最近的一条数据,而且格式很规范,很整齐。
{
        "_id" : ObjectId("4f0bc1245a5904bae2b767a8"),
        "title" : "wowowowo",
        "content" : "hahahahah",
        "time" : ISODate("2012-01-10T03:38:45.515Z")
}
> db.blog.find({"title":"wowowowo"}) //使用find()查找键为title,值为"wowowowo"的所有文档,结果如下。
{ "_id" : ObjectId("4f0bc1245a5904bae2b767a8"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z") }
{ "_id" : ObjectId("4f0bc11d5a5904bae2b767a7"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z"), "comments" : "hao a
 hao a " }
> db.blog.findOne({"title":"wowowowo"}) //使用findOne()查找键为title,值为"wowowowo"的最近的一个文档。结果如下。
{
        "_id" : ObjectId("4f0bc1245a5904bae2b767a8"),
        "title" : "wowowowo",
        "content" : "hahahahah",
        "time" : ISODate("2012-01-10T03:38:45.515Z")
}
>

那么,我想指定返回的键,某些键显示出来,某些键不显示出来,如何做到。其实也可以。就用到find(,,)函数中的第二个参数了,看实例:

> db.blog.findOne({},{"title":1,"content":1})  //使用findOne()的第二个参数,设定为1,查询结果只显示title和content,_id这个键总是被返回。
{
        "_id" : ObjectId("4f0bc1245a5904bae2b767a8"),
        "title" : "wowowowo",
        "content" : "hahahahah"
}
> db.blog.findOne({},{"title":0,"content":0})  //设定为0,则查询结果不显示。等同于{"time":1}.
{
        "_id" : ObjectId("4f0bc1245a5904bae2b767a8"),
        "time" : ISODate("2012-01-10T03:38:45.515Z")
}
> db.blog.findOne({},{"title":0}) //不显示title
{
        "_id" : ObjectId("4f0bc1245a5904bae2b767a8"),
        "content" : "hahahahah",
        "time" : ISODate("2012-01-10T03:38:45.515Z")
}
> db.blog.findOne({},{"time":0,"_id":0})  //也可以把_id也不显示。
{ "title" : "wowowowo", "content" : "hahahahah" }
> db.blog.findOne({},{"time":0,"_id":1}) //不能这样,错误!要么全是1.要么全是0 。
Fri Jan 13 10:43:34 uncaught exception: error {
        "$err" : "You cannot currently mix including and excluding fields. Conta
ct us if this is an issue.",
        "code" : 10053
}
>

2.查询条件

上面是简单的查询,要想复杂的查询,就必须要加上查询条件,比如and ,or ,取反啊等等。

1.查询条件

“$lt”、"$lte"、“$gt”、“$gte”就是比较操作符,相当于<、<=、>、>=。

> db.user.find({"age":{"$lt":30,"$gte":20}}) //查询20<=age<30的文档。
{ "_id" : ObjectId("4f0d057b081c6af197458524"), "age" : 22, "email" : [ "3@qq.co
m", "5@qq.com" ], "relationships" : { "friend" : 1000, "enemies" : 2 }, "sex" :
[ "nv", "nan", "no" ], "username" : "joe" }
>

2.or查询

MongoDB中有两种方式查询OR。“$in”和“$nin” ,在这个范围内,不在这个范围内。

> db.user.find({"age":{"$in":[10,22,34]}})  //区间,用中括号[].切记。
{ "_id" : ObjectId("4f0d057b081c6af197458524"), "age" : 22, "email" : [ "3@qq.co
m", "5@qq.com" ], "relationships" : { "friend" : 1000, "enemies" : 2 }, "sex" :
[ "nv", "nan", "no" ], "username" : "joe" }
>

$or 是或的另一种表达形式,也是主要的或,范围比较广,比较的复杂的或。

> db.blog.find({"$or":[{"title":"wowowowo"},{"content":"hao a hao a "}]})  //注意书写形式,[].
{ "_id" : ObjectId("4f0bc1245a5904bae2b767a8"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z") }
{ "_id" : ObjectId("4f0bc11d5a5904bae2b767a7"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z"), "comments" : "hao a
 hao a " }
>


3.$where查询

在Mongo系统中,键/值对是很有表现力的查询方式,但是依然有些需求它无法表达,当其他方法都败下阵下来时,就轮到“$where”了。用它可以执行任意的javascript作为查询的一部分,这使得查询能做(几乎)任何事情。

最典型的例子是比较一个文档中两个键的值是否相等。先插入两个文档到新建的foo集合中去,现在想查找文档中两个键的值是相同的一个文档,怎么办?

> db.foo.insert({"apple":1,"banana":6,"peach":3})
> db.foo.insert({"apple":1,"spinach":4,"watermelon":4})

可以用到"$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;
... }}); //函数结束。输出结果。
{ "_id" : ObjectId("4f13cf7cae966b8ccbff69f2"), "apple" : 1, "spinach" : 4, "wat
ermelon" : 4 }
>

3.查询的几个限制limit ,skip,sort。

在mysql中也有limit表示限制查询的数量,用order by  * (desc)来表示升序降序。在MongoDB中也用limit( )条件表示限制查询的数量。用sort( )来用查询结果中的一个键来排序。skip( )表示跳过多少个,再来查询结果。

> db.blog.find().limit(1) //使用limit( )只显示一个结果出来。
{ "_id" : ObjectId("4f0bc1245a5904bae2b767a8"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z") }
>
> db.blog.find().skip(2) //表示跳过前往2个。再查询所有。
{ "_id" : ObjectId("4f0cf96bbc8c53013bb90682"), "title" : "okokok", "content" :
"123456", "time" : "2011023023", "comments" : "23224" }
>
> db.blog.find().sort({time:1,comments:-1}) //安装time的升序,comments的降序排列查询结果。1表升序,-1表降序。
{ "_id" : ObjectId("4f0cf96bbc8c53013bb90682"), "title" : "okokok", "content" :
"123456", "time" : "2011023023", "comments" : "23224" }
{ "_id" : ObjectId("4f0bc11d5a5904bae2b767a7"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z"), "comments" : "hao a
 hao a " }
{ "_id" : ObjectId("4f0bc1245a5904bae2b767a8"), "title" : "wowowowo", "content"
: "hahahahah", "time" : ISODate("2012-01-10T03:38:45.515Z") }
>

也可以把这几个组合起来,对于分页来讲非常有用。

比如:你有个商店,有人想搜索MP3,若是想每页返回50个结果,而且是按价格从高到低排序,可以这样写:

>db.stock.find({"name":"mp3"}).limit(50).sort("price":-1);

点击”下一页“,可以看到更多结果,那么如何做呢?可以用到skip( )了。

>db.stock.find({"name":"mp3"}).limit(50).skip(50).sort({"price":-1});

不过skip( )略过多的结果,可能导致问题,少量的可以,当大量的文档时候,容易紊乱出错。

抱歉!评论已关闭.