mongodb查询find(2012-01-05 11:38:10)
mongodb查询find
指定返回的键,通过find或findOne的第二个参数指定想要的键。
> db.visithomepage.find({},{"user_id" : 1,"time" :1})
{ "_id" : ObjectId("4e0713be3ded0ab30ccb4b81"), "user_id" : NumberLong(22715364), "time" : NumberLong(1305108928) }
把不需要看到的,改成0,比如把_id改成0,不让他回复。
> db.visithomepage.find({},{"user_id" : 1,"time" :1,"_id" : 0}) { "user_id" : NumberLong(23020418), "time" : NumberLong(1305105014) }
限制:不可以引用文档中其他键的值。
--------------------------------------------------------------------------------
查询条件:
$lt,$lte,$gt,$gte,$ne < <= > >= ≠ > db.visithomepage.find({"user_id" : { "$lte" : 23011003,"$gte" : 23010000}})
查找日期 start = new Date("01/01/2007") db.visithomepage.find({registered" : { "$lt" : start }})
Or查询 $in 和 $or > db.visithomepage.find({"user_id" : { "$in" : [23011003, 23010000]}})
当然还有$nin
$in能对单个键做查询。要是对多个键做查询,就要用$or了,$or的优化在于第一个条件竟可能的匹配更多的文档。
> db.visithomepage.find({"$or" : [{"user_id" : 23011003}, {"time" : 1305115967}]})
$nin 不包含 查询age的值在7,8 范围外的数据 db.c1.find({age:{$nin: [7,8]}});
--------------------------------------------------------------------------------
$not
他是元条件,可以用在任何其他条件之上。
例如$mod取模运算符来说, db.users.find({"user_id" : {"$mod" : [5, 1]}}) 上面的查询会返回1,6,11,16等用户。要是想返回2,3,4,5,7,8,9,10,12等用户就要用$not了 db.users.find({"user_id" : {"$not" :{"$mod" : [5, 1]}}})
--------------------------------------------------------------------------------
正则表达式 db.users.find({"name" : /zorpia/i}) 支持perl的pcre库来匹配正则表达式
查询name 不以T开头的数据 db.c1.find({name: {$not: /^T.*/}});
--------------------------------------------------------------------------------
查询数组 db.zorpia.insert({"fruit" : ["apple","banana","peach"]})
用下面的查询: db.zorpia.find({"fruit" : "banana"})
1.$all 如果需要通过多个元素来匹配数组,用$all,例如: db.zorpia.insert({"fruit" : ["apple","banana","peach"]}) db.zorpia.insert({"fruit" : ["apple","kumquat","orange"]}) db.zorpia.insert({"fruit" : ["cherry","banana","apple"]}) 要找到有apple和banana的文档,用$all db.zorpia.find({"fruit" : {$all : ["apple", "banana"]}}) 要是想查询数组指定位置的元素,则用语法指定下标,例如: db.zorpia.find({"fruit.2" :"peach"}) 上面这个会匹配第三个元素是peach的文档
2.$size数组元素个数 用来查询指定长度的数组 db.zorpia.find({"fruit" : {"$size" : 3}}) 查询3个长度的数组,但是他不能和其他查询子句组合,例如$gt
3.$slice 返回前10条评论 db.zorpia.post.findOne(criteria, { "comments" : {$slice : 10}}) 返回最后10条 db.zorpia.post.findOne(criteria, { "comments" : {$slice : -10}}) 返回24-33个元素 db.zorpia.post.findOne(criteria, { "comments" : {$slice : [23,10]}}) 不过他们都会返回所有的键
--------------------------------------------------------------------------------
查询内嵌文档 "name" : { "firstname" : "joe", "lastname" : "schmoe" }
可以用下面的查询joe schmoe的人,很烦,firstname和lastname一定要写全,而且first和last的次序不能点到。
> db.users.findOne({"name" : {"firstname":"joe","lastname" : "schmoe"}})
正确的方法,用。号 > db.users.findOne({"name.firstname":"joe"}) { "_id" : ObjectId("4e0310f40611960df1e86a95"), "emails" : [ "joe4@alexhe.net", "joe5@zorpia.com", "joe6@zorpia.com" ], "name" : { "firstname" : "joe", "lastname" : "schmoe" } } 注意,点表示法也是待插入的文档不能包含“。”。如果我们保存url就会碰到问题。解决方法是插入前或者提取后执行一个全局替换,将。替换为url中的非法字符。
当文档结构复杂后。假设有博客文章若干,要找到joe发飙的5分以上的评论。博客文章的结构如下: > db.blog.find() { "content" : "...", "comments" : [ { "author" : "joe", "score" : 3, "comment" : "nice post" }, { "author" : "mary", "score" : 6, "comment" : "6 fen" } ] } 只能用$elemMatch进行匹配。这种模糊的命名条件能用来部分指定匹配数组中的单个内嵌文档的限定条件。 db.blog.find({"comments" : { "$elemMatch" : {"author" : "joe","score" : {"$gte" : 5}}}})
--------------------------------------------------------------------------------
$where p55 它可以执行任意JavaScript作为查询的一部分。这方面我还不是很明白,以后再研究。需要大家自己研究了。
注意:尽量避免使用$where查询。速度上要比常规查询慢很多。每个文档要从bson转换成JavaScript对象,然后通过$where的表达式来运行。同样他不能利用索引。
--------------------------------------------------------------------------------
游标 var cursor = db.users.find() > while (cursor.hasNext()) { obj = cursor.next(); }
cursor.hasNext()检查时候有后续结果存在,然后用cursor.next()将其获得。
也能用forEach: var cursor = db.users.find() cursor.forEach(function(x) { print(x.name); });
--------------------------------------------------------------------------------
limit,skip和sort
limit函数,例如只返回3个结果。 db.users.find().limit(3) limit是上限,不是下限
skip与limit类似: db.users.find().skip(3) 会略过前三个匹配的文档,然后返回余下的文档。如果集合少于三个文档,则不会返回任何文档。
sort用一个对象作为参数:1代表升序,-1降序。如果指定了多个键,则按照多个键的顺序依次排序。 db.users.find().sort({"username" : 1, "age" : -1})
以上三个方法可以组合使用。处理分页很有用。例如,有人想搜索mp3。如果每页返回50个结果,而且按照价格从高到底排序: db.stock.find({"desc" : "mp3"}).limit(50).sort({"price" : -1})
下一页只要略过50个就行了。 db.stock.find({"desc" : "mp3"}).skip(50).limit(50).sort({"price" : -1})
应当避免略过过多的结果。
统计 db.things.count(); // select count(*) from things; db.things.find({ x: 10}).count(); // select count(*) from things where x=10; 以下返回的不是5,而是user 表中所有的记录数量 db.users.find().skip(10).limit(5).count(); 如果要返回限制之后的记录数量,要使用count(true)或者count(非0) db.users.find().skip(10).limit(5).count(true);
多条件查询 db.things.find( { x : 3, y : "foo" } ); // where x = 3 and y = "foo"
指定返回结果集条件 db.things.find().limit(10); // limit 10, db.things.find().skip(7).limit(10); // limit 7, 10
排序 db.things.find().sort({$natural: 1}); // order by _id ASE db.things.find().sort({$natural: -1}); // order by _id DESE db.things.find().sort({x: 1}); // order by x ASC db.things.find().sort({x: -1}); //order by x DESC db.things.find().sort({x: 1, y: -1}); // ~.~
取模 db.things.find( { x : { $mod : [ 10 , 1 ] } } ); // where x=1
与数值元素匹配 db.things.find({ x : { $in: [2, 4, 6]}}); // x in array db.things.find({ x: { $nin: [2, 4, 6]}}); // x not in array
$all 匹配所有 这个操作符跟SQL语法的in类似,但不同的是, in只需满足( )内的某一个值即可, 而$all必
须满足[ ]内的所有值,例如: db.users.find({age : {$all : [6, 8]}}); 可以查询出 {name: 'David', age: 26, age: [ 6, 8, 9 ] } 但查询不出 {name: 'David', age: 26, age: [ 6, 7, 9 ] }
$exists 判断字段是否存在
查询所有存在age字段的记录 db.users.find({age: {$exists: true}}); 查询所有不存在name字段的记录 db.users.find({name: {$exists: false}});
Null 值处理
> db.c2.find({age:null})
$mod 取模运算
查询age取模6等于1的数据
db.c1.find({age: {$mod : [ 6 , 1 ] } })
$ne 不等于
查询x的值不等于3 的数据 db.c1.find( { age : { $ne : 7 } } );
Javascript 查询和$Where查询
查询a大于3的数据,下面的查询方法殊途同归 db.c1.find( { a : { $gt: 3 } } ); db.c1.find( { $where: "this.a > 3" } ); db.c1.find("this.a > 3"); f = function() { return this.a > 3; } db.c1.find(f);
存储过程
关于存储过程你需要知道的第一件事就是它是用 javascript来写的。 MongoDB 存储过程是存储在db.system.js表中的,我们想象一个简单的sql自定义函数如下:
function addNumbers( x , y ) {
return x + y; } 下面我们将这个sql自定义函数转换为MongoDB 的存储过程:
> db.system.js.save({_id:"addNumbers", value:function(x, y){ return x + y; }});
存储过程可以被查看,修改和删除,所以我们用 find 来查看一下是否这个存储过程已经被创建上了。 > db.system.js.find() 调用一下这个存储过程: db.eval_r('addNumbers(3, 4.2)');
db.eval_r()是一个比较奇怪的东西,我们可以将存储过程的逻辑直接在里面并同时调用,而无需事先声明存储过程的逻辑。
db.eval_r( function() { return 3+3; }