MongoDB管理与开发精要《红丸出品》4.6 查询记录

----------------------------------------------------------------------------------------------------------------
《MongoDB管理与开发精要》、《Redis实战》作者
@CD红丸                    http://weibo.com/u/2446082491
----------------------------------------------------------------------------------------------------------------

4.6.1普通查询

在没有深入查询之前, 我们先看看怎么从一个查询中返回一个游标对象.可以简单的通过 find() 来查询,他返回一个任意结构的集合. 如果实现特定的查询稍后讲解.

实现上面同样的查询, 然后通过 while来输出:

> var cursor = db.things.find();

> while (cursor.hasNext()) printjson(cursor.next());

{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }

{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }

{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x" : 4, "j" : 2 }

{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }

{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x" : 4, "j" : 5 }

上面的例子显示了游标风格的迭代输出. hasNext() 函数告诉我们是否还有数据,如果有则可以调用 next() 函数.

 

当我们使用的是 JavaScript shell, 可以用到JS的特性, forEach就可以输出游标了. 下面的例子就是使用 forEach()来循环输出:  forEach() 必须定义一个函数供每个游标元素调用.

> db.things.find().forEach(printjson);

{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }

{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }

{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x" : 4, "j" : 2 }

{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }

{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x" : 4, "j" : 5 }

 

MongoDB shell ,我们也可以把游标当作数组来用:

> var cursor = db.things.find();

> printjson(cursor[4]);

{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }

 

使用游标时候请注意占用内存的问题, 特别是很大的游标对象,有可能会内存溢出. 所以应该用迭代的方式来输出.下面的示例则是把游标转换成真实的数组类型:

> var arr = db.things.find().toArray();

> arr[5];

{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }

 

请注意这些特性只是在MongoDB shell里使用,而不是所有的其他应用程序驱动都支持. MongoDB 游标对象不是没有快照,如果有其他用户在集合里第一次或者最后一次调用 next(),你可能得不到游标里的数据. 所以要明确的锁定你要查询的游标.

4.6.2条件查询

到这里我们已经知道怎么从游标里实现一个查询并返回数据对象, 下面就来看看怎么根据指定的条件来查询.

下面的示例就是说明如何执行一个类似SQL的查询,并演示了怎么在 MongoDB 里实现.这是在MongoDB shell里查询,当然你也可以用其他的应用程序驱动或者语言来实现:

                                                SELECT * FROM things WHERE name="mongo"

> db.things.find({name:"mongo"}).forEach(printjson);

{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }

 

SELECT * FROM things WHERE x=4

> db.things.find({x:4}).forEach(printjson);

{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }

{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x" : 4, "j" : 2 }

{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }

{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x" : 4, "j" : 5 }

查询条件是 { a:A, b:B, }类似“where a==A and b==B and …”.

 

上面显示的是所有的元素, 当然我们也可以返回特定的元素,类似于返回表里某字段的值, 只需要在 find({x:4})里指定元素的名字

SELECT j FROM things WHERE x=4

> db.things.find({x:4}, {j:true}).forEach(printjson);

{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "j" : 1 }

{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "j" : 2 }

{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "j" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "j" : 4 }

{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "j" : 5 }

4.6.3 findOne()语法

为了方便考虑, MongoDB shell避免游标可能带来的开销,提供一个findOne() 函数.这个函数和 find() 函数一样,不过它返回的是游标里第一条数据, 或者返回null,即空数据.

 

作为一个例子, name=”mongo” 可以用很多方法来实现,可以用 next() 来循环游标或者当做数组返回第一个元素.

 

但是用 findOne() 方法则更简单和高效:

> printjson(db.things.findOne({name:"mongo"}));

{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }

4.6.4通过limit限制结果集数量

如果需要限制结果集的长度, 那么可以调用 limit方法.

这是强烈推荐解决性能问题的方法, 就是通过限制条数来减少网络传输,例如:

> db.things.find().limit(3);

{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }

{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值