来:http://blog.csdn.net/wangli61289/article/details/40623097

https://docs.mongodb.org/manual/reference/sql-aggregation-comparison/

【第一个查询参数】

find函数第一个参数是一个文档,其中给出了我们要查询集合中什么样文档的描述。如果我们要查询所有文档,可以不带任何参数调用find函数,或第一个参数为空文档{},如下例:

  1. > db.people.find();
  2. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  3. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  4. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  5. > db.people.find({});
  6. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  7. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  8. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  9. >

对于第一个代表查询参数的文档,我们该如何理解呢?比如我们执行 db.people.find({"age":18}),这个函数实际表示我们要查询键"age"的值为18的文档,键“age”的值不等于18或不存在这个键的文档均不会被查询到。再比如我们执行这个函数:db.people.find({"name":"jimmy", "age":18}),这个实际表示得是查询键“name”的值为"jimmy"并且键"age"的值为18的文档,即查询文档中各个条件是AND的关系!

在使用第一个参数时,我们需要注意一点:该查询文档中“键值对”中的值必须为常量!

【第二个查询参数】

上例中,我们不指定或只指定find函数第一个参数查询得到的文档,会包含原集合文档所有的键值对。这种情况对于某些键值对特别多的文档并不适用,因为我们可能只关心该文档的某几个键值对。这时我们可以使用find函数的第二个参数,来指定返回的键值对,这样还可以减少传输的数据量从而加快效率。第二个参数同样是个文档,如下例:

  1. > db.people.find({},{"age":1,"name":1});
  2. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  3. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  4. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  5. > db.people.find({},{"age":1});
  6. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18 }
  7. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28 }
  8. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38 }
  9. > db.people.find({},{"name":1});
  10. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "name" : "tom" }
  11. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "name" : "jimmy" }
  12. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "name" : "tim" }
  13. > db.people.find({},{"name":1,"_id":0});
  14. { "name" : "tom" }
  15. { "name" : "jimmy" }
  16. { "name" : "tim" }
  17. >

使用find函数第二个参数,对于这个文档我们有这些要注意的:

1》 对于非"_id"的所有键,其值要么同时不等于0(表明要查询该键值对),要么同时等于0(表明要忽略该键值对),否则执行报错。

2》 对于非“_id”的所有键,如果其值全部为0,则此时如果也指明了键“_id”的情况,则键“_id”的值必须为0,否则执行报错。

3》 对于键“_id”,如果不指名其值,则查询结果中肯定包含这个键值对,如果不想包含,可以指明其值为0即可。

综上,我们总结一下如果需要使用第二个参数,则使用的技巧为:指明所有需要得到的键的值为非0的数字,如果还要过滤键"_id",则再指明"_id"这个键值为0即可。

【查询条件】

上面提到的查询条件,都是精确匹配,即“=”多少。MongoDB中的查询显然还有更复杂的匹配。比如范围,OR子句和取反等。我们分别进行介绍。

“$lt”、“$lte”、“$gt”、“$gte” 就是所有的范围比较操作符,分别对应<、<=、>、>=。将他们组合应用,就可以查询值在某个范围内的文档了,比如我们要查询18-30岁(含)的所有用户:

  1. > db.people.find({"age":{"$gte":18,"$lte":30}});
  2. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  3. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  4. >

这种范围查询操作符,除用在值为数字的键之上外,对于值为日期的键的范围匹配也尤为好用!比如我们要查询注册日期在2007/05/01前的用户信息,我们可以这样写:

  1. > db.user.find();
  2. { "_id" : ObjectId("5020faf5d6acd1b2a3fb316f"), "name" : "tim", "age" : 40, "reg
  3. istered" : ISODate("2007-03-02T16:00:00Z") }
  4. { "_id" : ObjectId("5020fb08d6acd1b2a3fb3170"), "name" : "tom", "age" : 29, "reg
  5. istered" : ISODate("2009-07-02T16:00:00Z") }
  6. { "_id" : ObjectId("5020fb27d6acd1b2a3fb3171"), "name" : "jimmy", "age" : 18, "r
  7. egistered" : ISODate("2009-09-02T16:00:00Z") }
  8. > db.user.find({"registered":{"$lte":new Date("2007/05/01")}});
  9. { "_id" : ObjectId("5020faf5d6acd1b2a3fb316f"), "name" : "tim", "age" : 40, "reg
  10. istered" : ISODate("2007-03-02T16:00:00Z") }
  11. >

有时我们需要查询某个键不等于某个值的文档,我们可以使用这个条件操作符"$ne",他表示不相等。如我们要查询注册用户名不等于“tom”的文档:

  1. > db.user.find({"name":{"$ne":"tom"}});
  2. { "_id" : ObjectId("5020faf5d6acd1b2a3fb316f"), "name" : "tim", "age" : 40, "reg
  3. istered" : ISODate("2007-03-02T16:00:00Z") }
  4. { "_id" : ObjectId("5020fb27d6acd1b2a3fb3171"), "name" : "jimmy", "age" : 18, "r
  5. egistered" : ISODate("2009-09-02T16:00:00Z") }
  6. >

条件操作符"$ne"适合于所有类型的值!

【OR查询】

MongoDB中有两种方式进行OR查询:“$in”可以用来查询一个键的多个值,“$or”则更通用一些,可以用来完成多个键值对的组合。我们也分别演示一下:我们要查询奖券号码为10,20,30 的所有投注者的姓名:

  1. > db.raffle.find({})
  2. { "_id" : ObjectId("50210091d6acd1b2a3fb3172"), "name" : "tim", "ticket_no" : 11 }
  3. { "_id" : ObjectId("5021009bd6acd1b2a3fb3173"), "name" : "tom", "ticket_no" : 20 }
  4. { "_id" : ObjectId("502100a8d6acd1b2a3fb3174"), "name" : "jimmy", "ticket_no" : 30 }
  5. > db.raffle.find({"ticket_no":{"$in":[10,20,30]}}, {"name":1})
  6. { "_id" : ObjectId("5021009bd6acd1b2a3fb3173"), "name" : "tom" }
  7. { "_id" : ObjectId("502100a8d6acd1b2a3fb3174"), "name" : "jimmy" }
  8. >

但如果还要求我们查询出奖券号码为10,20,30 或投注者姓名为“tim”的所有投注信息,我们单纯用"$in"是无法胜任的,我们可以用操作符"$or",“$or”操作符可以组合其他操作符如"$in"拼凑的条件:

  1. > db.raffle.find({})
  2. { "_id" : ObjectId("50210091d6acd1b2a3fb3172"), "name" : "tim", "ticket_no" : 11 }
  3. { "_id" : ObjectId("5021009bd6acd1b2a3fb3173"), "name" : "tom", "ticket_no" : 20 }
  4. { "_id" : ObjectId("502100a8d6acd1b2a3fb3174"), "name" : "jimmy", "ticket_no" : 30 }
  5. > db.raffle.find({"$or":[{"ticket_no":{"$in":[10,20,30]}},{"name":"tim"}]});
  6. { "_id" : ObjectId("50210091d6acd1b2a3fb3172"), "name" : "tim", "ticket_no" : 11 }
  7. { "_id" : ObjectId("5021009bd6acd1b2a3fb3173"), "name" : "tom", "ticket_no" : 20 }
  8. { "_id" : ObjectId("502100a8d6acd1b2a3fb3174"), "name" : "jimmy", "ticket_no" : 30 }
  9. >

使用“$or”操作符,其值为一个条件数组,数组中各个条件最后通过or组合。使用这个条件操作符有一个最佳实践是:将最宽松的条件放在前面,这样可以加快文档匹配速度!

【$mod 和 $not】

$mod操作符,使用格式为 {"键":{"$mod":[num1, num2]}},查询“键”的值对num1取余,如果这个值等于num2,则整条文档符合条件。如我们要查询所有在其本命年的用户(年龄是12的整数倍):

  1. > db.people.find();
  2. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  3. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  4. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  5. { "_id" : ObjectId("50210579d6acd1b2a3fb3175"), "age" : 36, "name" : "cliff" }
  6. > db.people.find({"age":{"$mod":[12,0]}});
  7. { "_id" : ObjectId("50210579d6acd1b2a3fb3175"), "age" : 36, "name" : "cliff" }
  8. >

$not是元条件符,即可以用于任何其他条件之上的,表明取反,还是上面的例子,我们这次要查所有不在其本命年的用户文档信息:

  1. > db.people.find();
  2. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  3. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  4. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  5. { "_id" : ObjectId("50210579d6acd1b2a3fb3175"), "age" : 36, "name" : "cliff" }
  6. > db.people.find({"age":{"$not":{"$mod":[12,0]}}});
  7. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  8. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  9. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  10. >

$not条件符配合正则表达式使用非常强大,这里先预报一下,我们后续会提到引入正则表达式的查询。

【特定于类型的查询】

查询某键,其值为null的文档时,我们会发现一个奇怪的现象,我们先看一个例子:

  1. > db.cc.find();
  2. { "_id" : ObjectId("50210861d6acd1b2a3fb3176"), "x" : 0, "y" : null }
  3. { "_id" : ObjectId("50210867d6acd1b2a3fb3177"), "x" : 0, "y" : 1 }
  4. { "_id" : ObjectId("5021086ad6acd1b2a3fb3178"), "x" : 0, "y" : 2 }
  5. > db.cc.find({"y":null});
  6. { "_id" : ObjectId("50210861d6acd1b2a3fb3176"), "x" : 0, "y" : null }
  7. >

利用值为null的条件貌似可以查询正确的文档,但我们忽略了如果集合中存在没有键"y"的文档,会出现什么情况:

  1. > db.cc.find();
  2. { "_id" : ObjectId("50210861d6acd1b2a3fb3176"), "x" : 0, "y" : null }
  3. { "_id" : ObjectId("50210867d6acd1b2a3fb3177"), "x" : 0, "y" : 1 }
  4. { "_id" : ObjectId("5021086ad6acd1b2a3fb3178"), "x" : 0, "y" : 2 }
  5. { "_id" : ObjectId("5021097ed6acd1b2a3fb3179"), "x" : 0 }
  6. > db.cc.find({"y":null});
  7. { "_id" : ObjectId("50210861d6acd1b2a3fb3176"), "x" : 0, "y" : null }
  8. { "_id" : ObjectId("5021097ed6acd1b2a3fb3179"), "x" : 0 }
  9. >

果然不出意外,没有这个键的文档同样匹配值为null这种条件,如果我们需要过滤掉这种文档,需要另外一个条件操作符$exists,指明这个键必须存在:

  1. > db.cc.find();
  2. { "_id" : ObjectId("50210861d6acd1b2a3fb3176"), "x" : 0, "y" : null }
  3. { "_id" : ObjectId("50210867d6acd1b2a3fb3177"), "x" : 0, "y" : 1 }
  4. { "_id" : ObjectId("5021086ad6acd1b2a3fb3178"), "x" : 0, "y" : 2 }
  5. { "_id" : ObjectId("5021097ed6acd1b2a3fb3179"), "x" : 0 }
  6. > db.cc.find({"y":{"$in":[null],$exists:true}});
  7. { "_id" : ObjectId("50210861d6acd1b2a3fb3176"), "x" : 0, "y" : null }
  8. >

我们发现,因为MongoDB中没有提供类似于"$eq"这种相等的条件操作符,所以“=null”的判断只能通过{"$in":[null]}来实现!

【正则表达式】

正则表达式在任何语言中都是操作字符串的一大利器!在MongoDB的查询中,其依然威力不减。正则表达式可以灵活的匹配字符串类型的值。如我们要查询所有姓名为“joy”开头并且忽略大小写的用户文档:

  1. > db.people.find();
  2. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  3. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  4. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  5. { "_id" : ObjectId("50210579d6acd1b2a3fb3175"), "age" : 36, "name" : "cliff" }
  6. { "_id" : ObjectId("50210c32d6acd1b2a3fb317a"), "age" : 19, "name" : "Joe" }
  7. { "_id" : ObjectId("50210c3cd6acd1b2a3fb317b"), "age" : 29, "name" : "JoE" }
  8. { "_id" : ObjectId("50210c40d6acd1b2a3fb317c"), "age" : 29, "name" : "JoEy" }
  9. > db.people.find({"name":/joe.*/i});
  10. { "_id" : ObjectId("50210c32d6acd1b2a3fb317a"), "age" : 19, "name" : "Joe" }
  11. { "_id" : ObjectId("50210c3cd6acd1b2a3fb317b"), "age" : 29, "name" : "JoE" }
  12. { "_id" : ObjectId("50210c40d6acd1b2a3fb317c"), "age" : 29, "name" : "JoEy" }
  13. >

Shell中写正则表达式的方式和JavaScript的一致,写在一对“ // ”之间的就是正则表达式。具体正则表达式的一些写法大家可以参考正则表达式的相关规范。我们上面提到了操作符$not和正则表达式的联合使用,我们这边也演示一下:

  1. > db.people.find();
  2. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  3. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  4. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  5. { "_id" : ObjectId("50210579d6acd1b2a3fb3175"), "age" : 36, "name" : "cliff" }
  6. { "_id" : ObjectId("50210c32d6acd1b2a3fb317a"), "age" : 19, "name" : "Joe" }
  7. { "_id" : ObjectId("50210c3cd6acd1b2a3fb317b"), "age" : 29, "name" : "JoE" }
  8. { "_id" : ObjectId("50210c40d6acd1b2a3fb317c"), "age" : 29, "name" : "JoEy" }
  9. > db.people.find({"name":{"$not":/joe.*/i}});
  10. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  11. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  12. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  13. { "_id" : ObjectId("50210579d6acd1b2a3fb3175"), "age" : 36, "name" : "cliff" }
  14. >

我们可以看到使用$not是将其作为正则表达式的键,表明和这个正则表达式不匹配。我们在最前边也介绍了,MongoDB支持正则表达式这种数据类型,即“键值对”中允许“值”为正则表达式,对于这种键值对,正则表达式也可以匹配成功:

  1. > db.people.find();
  2. { "_id" : ObjectId("501dffc605f64f64b0765c53"), "age" : 18, "name" : "tom" }
  3. { "_id" : ObjectId("501dffcc05f64f64b0765c54"), "age" : 28, "name" : "jimmy" }
  4. { "_id" : ObjectId("501dffd005f64f64b0765c55"), "age" : 38, "name" : "tim" }
  5. { "_id" : ObjectId("50210579d6acd1b2a3fb3175"), "age" : 36, "name" : "cliff" }
  6. { "_id" : ObjectId("50210c32d6acd1b2a3fb317a"), "age" : 19, "name" : "Joe" }
  7. { "_id" : ObjectId("50210c3cd6acd1b2a3fb317b"), "age" : 29, "name" : "JoE" }
  8. { "_id" : ObjectId("50210c40d6acd1b2a3fb317c"), "age" : 29, "name" : "JoEy" }
  9. { "_id" : ObjectId("50210f63d6acd1b2a3fb317d"), "age" : 99, "name" : /joe/i }
  10. > db.people.find({"name":/joe/i});
  11. { "_id" : ObjectId("50210c32d6acd1b2a3fb317a"), "age" : 19, "name" : "Joe" }
  12. { "_id" : ObjectId("50210c3cd6acd1b2a3fb317b"), "age" : 29, "name" : "JoE" }
  13. { "_id" : ObjectId("50210c40d6acd1b2a3fb317c"), "age" : 29, "name" : "JoEy" }
  14. { "_id" : ObjectId("50210f63d6acd1b2a3fb317d"), "age" : 99, "name" : /joe/i }
  15. >

但注意正则表达式的匹配必须是完全匹配,即正则表达式的写法完全相同才可以匹配成功(这个在实际应用中基本不会遇见的)。

MongoDB可以为前缀型的正则表达式(/^joe/i)查询使用索引,所以这种前缀型的正则表式查询速度会很快!

这里再稍微提一下find函数和findOne函数的区别,刚才说了,find函数返回的是一个子集,而findOne就是返回一条文档或null(未查询到结果),对于一些可以接受文档做参数的函数如insert,可以直接使用findOne的返回值作为参数。

最后就这基本的查询条件操作符部分稍作总结,因为我们前面介绍修改器操作符也是以"$"开头,如“$set”,"$inc"等,这里介绍的查询条件操作符也是以"$"开头,那使用上有哪些区分呢?修改器操作符都是外层文档的键,而查询条件的操作符基本都是内层文档的键(注意“$or”是一个例外)。

select * from users;

db.users.find();

指定返回那些列(键):

select name, skills from users;

db.users.find({}, {'name' : 1, 'skills' : 1});

补充说明: 第一个{} 放where条件 第二个{} 指定那些列显示和不显示 (0表示不显示 1表示显示)

where条件:

1.简单的等于:

select name, age, skills from users where name = 'hurry';

db.users.find({'name' : 'hurry'},{'name' : 1, 'age' : 1, 'skills' : 1});

2.使用and

select name, age, skills from users where name = 'hurry' and age = 18;

db.users.find({'name' : 'hurry', 'age' : 18},{'name' : 1, 'age' : 1, 'skills' : 1});

3.使用or

select name, age, skills from users where name = 'hurry' or age = 18;

db.users.find({ '$or' : [{'name' : 'hurry'}, {'age' : 18}] },{'name' : 1, 'age' : 1, 'skills' : 1});

4.<, <=, >, >= ($lt, $lte, $gt, $gte )

select * from users where age >= 20 and age <= 30;

db.users.find({'age' : {'$gte' : 20, '$lte' : 30}});

5.使用in, not in ($in, $nin)

select * from users where age in (10, 22, 26);

db.users.find({'age' : {'$in' : [10, 22, 26]}});

6.匹配null

select * from users where age is null;

db.users.find({'age' : null);

7.like (mongoDB 支持正则表达式)

select * from users where name like "%hurry%";

db.users.find({name:/hurry/});

select * from users where name like "hurry%";

db.users.find({name:/^hurry/});

8.使用distinct

select distinct (name) from users;

db.users.distinct('name');

9.使用count

select count(*) from users;

dunt();

10.数组查询 (mongoDB自己特有的)

如果skills是 ['java','python']

db.users.find({'skills' : 'java'}); 该语句可以匹配成功

$all

db.users.find({'skills' : {'$all' : ['java','python']}}) skills中必须同时包含java 和 python

$size

db.users.find({'skills' : {'$size' : 2}}) 遗憾的是$size不能与$lt等组合使用

$slice

db.users.find({'skills' : {'$slice : [1,1]}})

两个参数分别是偏移量和返回的数量

11.查询内嵌文档

12.强大的$where查询
db.foo.find();                   
{ "_id" : ObjectId("4e17ce0ac39f1afe0ba78ce4"), "a" : 1, "b" : 3, "c" : 10 }
{ "_id" : ObjectId("4e17ce13c39f1afe0ba78ce5"), "a" : 1, "b" : 6, "c" : 6 }

如果要查询 b = c 的文档怎么办?

> 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("4e17ce13c39f1afe0ba78ce5"), "a" : 1, "b" : 6, "c" : 6 }

1 ) . 大于,小于,大于或等于,小于或等于
$gt:大于
$lt:小于
$gte:大于或等于
$lte:小于或等于
例子:
db.collection.find({ "field" : { $gt: value } } ); // greater than : field > value
db.collection.find({ "field" : { $lt: value } } ); // less than : field < value
db.collection.find({ "field" : { $gte: value } } ); // greater than or equal to : field >= value
db.collection.find({ "field" : { $lte: value } } ); // less than or equal to : field <= value

如查询j大于3,小于4:

db.things.find({j : {$lt: 3}});
db.things.find({j : {$gte: 4}});

也可以合并在一条语句内:

db.collection.find({ "field" : { $gt: value1, $lt: value2 } } ); // value1 < field < value

2) 不等于 $ne

例子:

db.things.find( { x : { $ne : 3 } } );

3) in 和 not in ($in $nin)
语法:
db.collection.find( { "field" : { $in : array } } );

例子:

db.things.find({j:{$in: [2,4,6]}});

db.things.find({j:{$nin: [2,4,6]}});

4) 取模运算$mod
如下面的运算:
db.things.find( "this.a % 10 == 1")

可用$mod代替:

db.things.find( { a : { $mod : [ 10 , 1 ] } } )

5)  $all
$all和$in类似,但是他需要匹配条件内所有的值:
如有一个对象:
{ a: [ 1, 2, 3 ] }

下面这个条件是可以匹配的:

db.things.find( { a: { $all: [ 2, 3 ] } } );

但是下面这个条件就不行了:

db.things.find( { a: { $all: [ 2, 3, 4 ] } } );

6)  $size
$size是匹配数组内的元素数量的,如有一个对象:{a:["foo"]},他只有一个元素:
下面的语句就可以匹配:
db.things.find( { a : { $size: 1 } } );

官网上说不能用来匹配一个范围内的元素,如果想找$size<5之类的,他们建议创建一个字段来保存元素的数量。

You cannot use $size to find a range of sizes (for example: arrays with more than 1 element). If you need to query for a range, create an extra size field that you increment when you add elements.

7)$exists

$exists用来判断一个元素是否存在:

如:

db.things.find( { a : { $exists : true } } ); // 如果存在元素a,就返回
db.things.find( { a : { $exists : false } } ); // 如果不存在元素a,就返回

8)  $type

$type 基于 bson type来匹配一个元素的类型,像是按照类型ID来匹配,不过我没找到bson类型和id对照表。

db.things.find( { a : { $type : 2 } } ); // matches if a is a string
db.things.find( { a : { $type : 16 } } ); // matches if a is an int

9)正则表达式
mongo支持正则表达式,如:
db.customers.find( { name : /acme.*corp/i } ); // 后面的i的意思是区分大小写

10)  查询数据内的值
下面的查询是查询colors内red的记录,如果colors元素是一个数据,数据库将遍历这个数组的元素来查询。
db.things.find( { colors : "red" } );

11) $elemMatch
如果对象有一个元素是数组,那么$elemMatch可以匹配内数组内的元素:
> t.find( { x : { $elemMatch : { a : 1, b : { $gt : 1 } } } } ) 
{ "_id" : ObjectId("4b5783300334000000000aa9"), 
"x" : [ { "a" : 1, "b" : 3 }, 7, { "b" : 99 }, { "a" : 11 } ]
}

$elemMatch : { a : 1, b : { $gt : 1 } } 所有的条件都要匹配上才行。

注意,上面的语句和下面是不一样的。

> t.find( { "x.a" : 1, "x.b" : { $gt : 1 } } )

$elemMatch是匹配{ "a" : 1, "b" : 3 },而后面一句是匹配{ "b" : 99 }, { "a" : 11 }

12)  查询嵌入对象的值
db.postings.find( { "author.name" : "joe" } );

注意用法是author.name,用一个点就行了。更详细的可以看这个链接: dot notation

举个例子:

> db.blog.save({ title : "My First Post", author: {name : "Jane", id : 1}})

如果我们要查询 authors name 是Jane的, 我们可以这样:

> db.blog.findOne({"author.name" : "Jane"})

如果不用点,那就需要用下面这句才能匹配:

db.blog.findOne({"author" : {"name" : "Jane", "id" : 1}})

下面这句:

db.blog.findOne({"author" : {"name" : "Jane"}})

是不能匹配的,因为mongodb对于子对象,他是精确匹配。

13) 元操作符 $not 取反

如:

db.customers.find( { name : { $not : /acme.*corp/i } } );

db.things.find( { a : { $not : { $mod : [ 10 , 1 ] } } } );

mongodb还有很多函数可以用,如排序,统计等,请参考原文。

mongodb目前没有或(or)操作符,只能用变通的办法代替,可以参考下面的链接:

+operations+in+query+expressions
分类: MongoDB

二、更新
mongodb更新有两个命令:
1).update()命令

db.collection.update( criteria, objNew, upsert, multi )

criteria : update的查询条件,类似sql update查询内where后面的
objNew   : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
upsert   : 这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi    : mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。

例:
db.test0.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } ); 只更新了第一条记录
db.test0.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true ); 全更新了
db.test0.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false ); 只加进去了第一条
db.test0.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true ); 全加进去了
db.test0.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );全更新了
db.test0.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );只更新了第一条

2).save()命令

db.collection.save( x )

x就是要更新的对象,只能是单条记录。

如果在collection内已经存在一个和x对象相同的"_id"的记录。mongodb就会把x对象替换collection内已经存在的记录,否则将会插入x对象,如果x内没有_id,系统会自动生成一个再插入。相当于上面update语句的upsert=true,multi=false的情况。
例:
db.test0.save({count:40,test1:"OK"}); #_id系统会生成
db.test0.save({_id:40,count:40,test1:"OK"}); #如果test0内有_id等于40的,会替换,否则插入。

mongodb的更新操作符:
1) $inc
用法:{ $inc : { field : value } }
意思对一个数字字段field增加value,例:
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 16, "test1" : "TESTTEST", "test2" : "OK", "test3" : "TESTTEST", "test4" : "OK", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $inc : { "count" : 1 } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 17, "test1" : "TESTTEST", "test2" : "OK", "test3" : "TESTTEST", "test4" : "OK", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $inc : { "count" : 2 } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 19, "test1" : "TESTTEST", "test2" : "OK", "test3" : "TESTTEST", "test4" : "OK", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $inc : { "count" : -1 } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : "TESTTEST", "test2" : "OK", "test3" : "TESTTEST", "test4" : "OK", "test5" : "OK" }

2) $set
用法:{ $set : { field : value } }
就是相当于sql的set field = value,全部数据类型都支持$set。例:
> db.test0.update( { "_id" : 15 } , { $set : { "test1" : "testv1","test2" : "testv2","test3" : "testv3","test4" : "testv4" } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : "testv1", "test2" : "testv2", "test3" : "testv3", "test4" : "testv4", "test5" : "OK" }

3) $unset
用法:{ $unset : { field : 1} }
顾名思义,就是删除字段了。例:
> db.test0.update( { "_id" : 15 } , { $unset : { "test1":1 } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test2" : "testv2", "test3" : "testv3", "test4" : "testv4", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $unset : { "test2": 0 } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test3" : "testv3", "test4" : "testv4", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $unset : { "test3":asdfasf } } );
Fri May 14 16:17:38 JS Error: ReferenceError: asdfasf is not defined (shell):0

> db.test0.update( { "_id" : 15 } , { $unset : { "test3":"test" } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test4" : "testv4", "test5" : "OK" }

没看出field : 1里面的1是干什么用的,反正只要有东西就行。

4) $push
用法:{ $push : { field : value } }
把value追加到field里面去,field一定要是数组类型才行,如果field不存在,会新增一个数组类型加进去。例:

> db.test0.update( { "_id" : 15 } , { $set : { "test1" : ["aaa","bbb"] } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "aaa", "bbb" ], "test4" : "testv4", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $push : { "test1": "ccc" } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "aaa", "bbb", "ccc" ], "test4" : "testv4", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $push : { "test2": "ccc" } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "aaa", "bbb", "ccc" ], "test2" : [ "ccc" ], "test4" : "testv4", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $push : { "test1": ["ddd","eee"] } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "aaa", "bbb", "ccc", [ "ddd", "eee" ] ], "test2" : [ "ccc" ], "test4" : "testv4", "test5" : "OK" }5) $pushAll

5) $pushAll
用法:{ $pushAll : { field : value_array } }
同$push,只是一次可以追加多个值到一个数组字段内。例:
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "aaa", "bbb", "ccc", [ "ddd", "eee" ] ], "test2" : [ "ccc" ], "test4" : "testv4", "test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $pushAll : { "test1": ["fff","ggg"] } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "aaa", "bbb", "ccc", [ "ddd", "eee" ], "fff", "ggg" ], "test2" : [ "ccc" ], "test4" : "testv4", "test5" : "OK" }

6)  $addToSet
用法:{ $addToSet : { field : value } }
增加一个值到数组内,而且只有当这个值不在数组内才增加。例:
> db.test0.update( { "_id" : 15 } , { $addToSet : { "test1": {$each : ["444","555"] } } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18,

"test1" : ["aaa","bbb","ccc",["ddd","eee"],"fff","ggg",["111","222"],"444","555"],

"test2" : [ "ccc" ], "test4" : "testv4", "test5" : "OK"

}
> db.test0.update( { "_id" : 15 } , { $addToSet : { "test1": {$each : ["444","555"] } } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18,

"test1" : ["aaa","bbb","ccc",["ddd","eee"],"fff","ggg",["111","222"],"444","555"], "test2" : [ "ccc" ],

"test4" : "testv4", "test5" : "OK"

}
> db.test0.update( { "_id" : 15 } , { $addToSet : { "test1": ["444","555"] } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18,

"test1" : ["aaa","bbb","ccc",["ddd","eee"],"fff","ggg",["111","222"],"444","555",["444","555"]], "test2" : [ "ccc" ],

"test4" : "testv4", "test5" : "OK"

}
> db.test0.update( { "_id" : 15 } , { $addToSet : { "test1": ["444","555"] } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : ["aaa","bbb","ccc",["ddd","eee"],"fff","ggg",["111","222"],"444","555",["444","555"]], "test2" : [ "ccc" ],

"test4" : "testv4", "test5" : "OK"

}

7) $pop
删除数组内的一个值
用法:
删除最后一个值:{ $pop : { field : 1 } }删除第一个值:{ $pop : { field : -1 } }
注意,只能删除一个值,也就是说只能用1或-1,而不能用2或-2来删除两条。mongodb 1.1及以后的版本才可以用,例:
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18,

"test1" : ["bbb","ccc",["ddd","eee"],"fff","ggg",["111","222"],"444"],

"test2" : [ "ccc" ], "test4" : "testv4", "test5" : "OK"

}
> db.test0.update( { "_id" : 15 } , { $pop : { "test1": -1 } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18,

"test1" : ["ccc",["ddd","eee"],"fff","ggg",["111","222"],"444"],

"test2" : [ "ccc" ], "test4" : "testv4", "test5" : "OK"

}
> db.test0.update( { "_id" : 15 } , { $pop : { "test1": 1 } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18,

"test1" : [ "ccc", [ "ddd", "eee" ], "fff", "ggg", [ "111", "222" ] ], "test2" : [ "ccc" ], "test4" : "testv4",
  "test5" : "OK"

}

8) $pull
用法:$pull : { field : value } }
从数组field内删除一个等于value值。例:
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "ccc", [ "ddd", "eee" ], "fff", "ggg", [ "111", "222" ] ], "test2" : [ "ccc" ], "test4" : "testv4",
"test5" : "OK" }

> db.test0.update( { "_id" : 15 } , { $pull : { "test1": "ggg" } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "ccc", [ "ddd", "eee" ], "fff", [ "111", "222" ] ], "test2" : [ "ccc" ], "test4" : "testv4", "test5"
: "OK" }

9) $pullAll
用法:{ $pullAll : { field : value_array } }
同$pull,可以一次删除数组内的多个值。例:
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ "ccc", [ "ddd", "eee" ], "fff", [ "111", "222" ] ], "test2" : [ "ccc" ], "test4" : "testv4", "test5"
: "OK" }

> db.test0.update( { "_id" : 15 } , { $pullAll : { "test1": [ "ccc" , "fff" ] } } );
> db.test0.find( { "_id" : 15 } );
{ "_id" : { "floatApprox" : 15 }, "count" : 18, "test1" : [ [ "ddd", "eee" ], [ "111", "222" ] ], "test2" : [ "ccc" ], "test4" : "testv4", "test5" : "OK" }

10) $ 操作符
$是他自己的意思,代表按条件找出的数组里面某项他自己。呵呵,比较坳口。看一下官方的例子:
> t.find()
{ "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] }

> t.update( {'comments.by':'joe'}, {$inc:{'comments.$.votes':1}}, false, true )

> t.find()
{ "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 4 }, { "by" : "jane", "votes" : 7 } ] }

需要注意的是,$只会应用找到的第一条数组项,后面的就不管了。还是看例子:
> t.find();
{ "_id" : ObjectId("4b9e4a1fc583fa1c76198319"), "x" : [ 1, 2, 3, 2 ] }
> t.update({x: 2}, {$inc: {"x.$": 1}}, false, true);
> t.find();

还有注意的是$配合$unset使用的时候,会留下一个null的数组项,不过可以用{$pull:{x:null}}删除全部是null的数组项。例:
> t.insert({x: [1,2,3,4,3,2,3,4]})
> t.find()
{ "_id" : ObjectId("4bde2ad3755d00000000710e"), "x" : [ 1, 2, 3, 4, 3, 2, 3, 4 ] }
> t.update({x:3}, {$unset:{"x.$":1}})
> t.find()
{ "_id" : ObjectId("4bde2ad3755d00000000710e"), "x" : [ 1, 2, null, 4, 3, 2, 3, 4 ] }

{ "_id" : ObjectId("4b9e4a1fc583fa1c76198319"), "x" : [ 1, 3, 3, 2 ] }

============  数组元素操作示例 ================

> db.arraytest.insert({id:2, name:'leon', comments:[{id:'011', content:'cmt11'}, {id:'012', content:'cmt12'}, {id:'013', content:'cmt13'}]})

1. 数组内的元素可以直接查询

> db.arraytest.find({'comments.id':'002'})

2. 更新数组中的某个节点的值,用$符号

db.arraytest.update({'comments.id':'012'}, {$set: {'comments.$.content':'cmtttt012'}})

3. 删除数组中的某一列,变成null

> db.arraytest.update({'comments.id':'012'}, {$unset: {'comments.$':1}})

4. 向数组中添加一个元素,如果之前没有元素则会新建数组

> db.arraytest.update({'comments.id':'112'}, {$push: {'comments.$.reply': {'rid':'r21', content:'reply22'}}}) 
============  数组元素操作示例 ================

MongoDB常用操作一查询find方法db.collection_name.find()的更多相关文章

  1. MongoDB常用操作一查询find方法(转)

    来:http://blog.csdn.net/wangli61289/article/details/40623097 https://docs.mongodb.org/manual/referenc ...

  2. mongodb常用操作语句

    mongodb常用操作语句 A:创建数据表 db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean&g ...

  3. MongoDB常用操作

    (备注: 对于 window, 不需要sudo) 验证成功与否: * 启动服务器: $sudo mongod --dbpath C:\data\db (需要 指明数据库存放的目录) * 打开shell ...

  4. MongoDB系列:二、MongoDB常用操作练习

    最近在自学MongoDB,在此记录一下,当做学习笔记了(不断更新中)!! 一.背景 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存 ...

  5. MongoDB常用操作整理

    Mongodb:是一种NoSQL数据库,NoSQL:Not Only SQLSQL: 数据表->JDBC读取->POJO(VO.PO)->控制层转化为JSON数据->客户端 这 ...

  6. MongoDB常用操作总结

    ====================================MGDB的操作====================================== 0.创建数据库时使用(use 数据库 ...

  7. Day07 数据类型(列表,元组,字典,集合)常用操作和内置方法

    数据类型 列表list: 用途:记录多个值(同种属性) 定义方式:[]用逗号分隔开多个任意类型的值 list()造出来的是列表,参数是可迭代对像,也就是可以使用for循环的对像 传入字典,出来的列表元 ...

  8. MongoDB常用操作--简介

    mongodb在项目中使用越来越觉得日志方面的记录和查询是远远优于MySQL的,所以对其一些基本的操作进行了整理,以下就是整理的一些规则插入数据: insert插入多组数据:inserrAll修改数据 ...

  9. 转:oralce常用操作、查询语句(查看表空间)

    http://highill.iteye.com/blog/1534858 最近整理一下oralce的常用语句,借此记录一下,在网上都应该能搜到,这里主要是整理分享. 一.操作语句 建立表空间 MYD ...

随机推荐

  1. 下载安装APK

    protected void downloadApk() { //apk下载链接地址,放置apk的所在路径 //1,判断sd卡是否可用,是否挂在上 if(Environment.getExternal ...

  2. C++ 多线程中的一个抛出异常

    试了一下,和Java完全不同. 注意Java和C++对于多线程里面的一个线程抛出异常的影响,完全不同. Java里面,对于主线程和其他线程完全不受影响: C++里面,整个程序会退出,所有线程都会受影响 ...

  3. JavaScript屏蔽Backspace键

    原文:http://www.cnblogs.com/xdp-gacl/p/3785806.html 今天在IE浏览器下发现,当把使用readonly="readonly"属性将文本 ...

  4. scala集合

    优先使用不可变集合.不可变集合适用于大多数情况,让程序易于理解和推断,因为它们是引用透明的( referentially transparent )因此缺省也是线程安全的. 使用可变集合时,明确地引用 ...

  5. mysql使用笔记(四)

    一.选择合适的数据类型 1. CHAR vs VCHAR     char是固定长度的字符类型,而varchar是可变长度的字符类型.char(M)的数据列中,每个值都占用M个字节,如果某个长度小于M ...

  6. Canu Parameter Reference(canu参数介绍)

    链接:Canu Parameter Reference To get the most up-to-date options, run canu -options The default values ...

  7. Unity 5 中的全局光照技术详解(建议收藏)

    本文整理自Unity全球官方网站,原文:UNITY 5 - LIGHTING AND RENDERING (文章较长,请耐心阅读)简介全局光照,简称GI,是一个用来模拟光的互动和反弹等复杂行为的算法, ...

  8. cocos2dx从入门到精通课程

    一.移动开发基础 二.cocos2dx跨平台理论 三.cocos2dx框架 四.cocos2dx内存管理 五.cocos2dx的事件与消息机制 六.cocos2dx的定时器 七.cocos2dx的渲染 ...

  9. RESEACH PAPER

      个,proquest的username和password赫然在目,别急,再看第4个结 果"HB Thompson Subscription Online Databases", ...

  10. 3.5 EF Code First总结

    1. 主键约定 属性名为“ID”(不区分大小写)或类名的后面跟有“ID”. 2. 关系约定 模型之间的关系,EF根据针对类型定义的导航属性来推断关系. 3. 连接字符串约定 (1)默认配置 如果连接字 ...