丰富的查询
MongoDB支持类似于SQL的>,>=,<,<=,<>,分别用 "$gt", "$gte", "$lt", "$lte", "$ne"表示,以及:$in,$nin,也支持条件的组合:and, or。
甚至还支持正则表达式,你没看错,正则表达式,强大吧。
> db.user.find()
{ "_id" : ObjectId("51f730c604f4bacbc87f67f2"), "name" : "jack", "age" : 53, "address" : { "country" : "CN", "city" : "Macao" }, "fav" : [ "apple", "banana" ], "email" : "[email protected]" }
{ "_id" : ObjectId("51f7312b04f4bacbc87f67f3"), "name" : "allen", "age" : 20, "address" : { "country" : "US", "city" : "NewYork" }, "email" : "[email protected]" }
>
> db.user.find({"age":{$lt:30}})
{ "_id" : ObjectId("51f7312b04f4bacbc87f67f3"), "name" : "allen", "age" : 20, "address" : { "country" : "US", "city" : "NewYork" }, "email" : "[email protected]" }
>
> db.user.find({"address.country":{$in:["CN","US"]},"age":{$gte:30}})
{ "_id" : ObjectId("51f730c604f4bacbc87f67f2"), "name" : "jack", "age" : 53, "address" : { "country" : "CN", "city" : "Macao" }, "fav" : [ "apple", "banana" ], "email" : "[email protected]" }
>
> db.user.find({"email":/[email protected]/})
{ "_id" : ObjectId("51f730c604f4bacbc87f67f2"), "name" : "jack", "age" : 53, "address" : { "country" : "CN", "city" : "Macao" }, "fav" : [ "apple", "banana" ], "email" : "[email protected]" }
>
{ "_id" : ObjectId("51f730c604f4bacbc87f67f2"), "name" : "jack", "age" : 53, "address" : { "country" : "CN", "city" : "Macao" }, "fav" : [ "apple", "banana" ], "email" : "[email protected]" }
{ "_id" : ObjectId("51f7312b04f4bacbc87f67f3"), "name" : "allen", "age" : 20, "address" : { "country" : "US", "city" : "NewYork" }, "email" : "[email protected]" }
>
> db.user.find({"age":{$lt:30}})
{ "_id" : ObjectId("51f7312b04f4bacbc87f67f3"), "name" : "allen", "age" : 20, "address" : { "country" : "US", "city" : "NewYork" }, "email" : "[email protected]" }
>
> db.user.find({"address.country":{$in:["CN","US"]},"age":{$gte:30}})
{ "_id" : ObjectId("51f730c604f4bacbc87f67f2"), "name" : "jack", "age" : 53, "address" : { "country" : "CN", "city" : "Macao" }, "fav" : [ "apple", "banana" ], "email" : "[email protected]" }
>
> db.user.find({"email":/[email protected]/})
{ "_id" : ObjectId("51f730c604f4bacbc87f67f2"), "name" : "jack", "age" : 53, "address" : { "country" : "CN", "city" : "Macao" }, "fav" : [ "apple", "banana" ], "email" : "[email protected]" }
>
另外MongoDB也提供了where子句,可以定义一个javascipt的predict函数来查询
> db.user.find({$where:function() {return this.address.city == 'Macao'}})
{ "_id" : ObjectId("51f730c604f4bacbc87f67f2"), "name" : "jack", "age" : 53, "address" : { "country" : "CN", "city" : "Macao" }, "fav" : [ "apple", "banana" ], "email" : "[email protected]" }
>
{ "_id" : ObjectId("51f730c604f4bacbc87f67f2"), "name" : "jack", "age" : 53, "address" : { "country" : "CN", "city" : "Macao" }, "fav" : [ "apple", "banana" ], "email" : "[email protected]" }
>
聚集函数
MongoDB也支持常用的聚集函数:count,distinct,group等
其中group较为复杂,需要指定初始值,和$reduce函数,
另外group还可以加condition指定过滤条件,finalize指定每组文档$reduce完成后的动作
> db.user.find()
{ "_id" : ObjectId("51f7560004f4bacbc87f67f4"), "name" : "brodie", "age" : 30, "gender" : "male", "address" : { "country" : "CN", "city" : "ShangHai" } }
{ "_id" : ObjectId("51f7562304f4bacbc87f67f5"), "name" : "dany", "age" : 28, "gender" : "male", "address" : { "country" : "CN", "city" : "ShangHai" } }
{ "_id" : ObjectId("51f7563d04f4bacbc87f67f6"), "name" : "davis", "age" : 31, "gender" : "male", "address" : { "country" : "CN", "city" : "WuHan" } }
{ "_id" : ObjectId("51f7566904f4bacbc87f67f7"), "name" : "jameson", "age" : 37, "gender" : "female", "address" : { "country" : "US", "city" : "NewYork" } }
>
> db.user.count({"age":{$gte:30}})
3
> db.user.distinct("address.country")
[ "CN", "US" ]
>
> db.user.group({
... "key":{"address.country":true},
... "initial":{"users":[]},
... "condition":{"age":{$gte:30}},
... "reduce":function(curdoc, predoc) {
... predoc.users.push(curdoc.name);
... },
... "finalize":function(predoc) {
... predoc.count = predoc.users.length;
... }
... })
[
{
"address.country" : "CN",
"users" : [
"brodie",
"davis"
],
"count" : 2
},
{
"address.country" : "US",
"users" : [
"jameson"
],
"count" : 1
}
]
{ "_id" : ObjectId("51f7560004f4bacbc87f67f4"), "name" : "brodie", "age" : 30, "gender" : "male", "address" : { "country" : "CN", "city" : "ShangHai" } }
{ "_id" : ObjectId("51f7562304f4bacbc87f67f5"), "name" : "dany", "age" : 28, "gender" : "male", "address" : { "country" : "CN", "city" : "ShangHai" } }
{ "_id" : ObjectId("51f7563d04f4bacbc87f67f6"), "name" : "davis", "age" : 31, "gender" : "male", "address" : { "country" : "CN", "city" : "WuHan" } }
{ "_id" : ObjectId("51f7566904f4bacbc87f67f7"), "name" : "jameson", "age" : 37, "gender" : "female", "address" : { "country" : "US", "city" : "NewYork" } }
>
> db.user.count({"age":{$gte:30}})
3
> db.user.distinct("address.country")
[ "CN", "US" ]
>
> db.user.group({
... "key":{"address.country":true},
... "initial":{"users":[]},
... "condition":{"age":{$gte:30}},
... "reduce":function(curdoc, predoc) {
... predoc.users.push(curdoc.name);
... },
... "finalize":function(predoc) {
... predoc.count = predoc.users.length;
... }
... })
[
{
"address.country" : "CN",
"users" : [
"brodie",
"davis"
],
"count" : 2
},
{
"address.country" : "US",
"users" : [
"jameson"
],
"count" : 1
}
]
MapReduce
MapReduce是比较复杂的聚集函数,但更加灵活。
map函数:指定的分组函数,其中调用emit分组,第一个参数为分组的键,value为reduce时需要的字段;
reduce函数:分组后的处理函数,参数key为分组的key,values为分组后的集合;
mapReduce的第三个参数指定输出的结合名称;
运行mapReduce后会输出执行的状态信息
下面用mapReduce作出上面group同样的效果
> var map = function() { ... emit(this.address.country, {user:this.name,age:this.age,count:1}); ... } > > var reduce = function(key, values) { ... var result = {users:[],count:0}; ... for (var i = 0; i < values.length; ++i) { ... if (values[i].age >= 30) { ... result.users.push(values[i].user); ... result.count += values[i].count; ... } ... } ... return result; ... } > > db.user.mapReduce(map,reduce, {"out":"user_by_country"}) { "result" : "user_by_country", "timeMillis" : 62, // time used "counts" : { "input" : 4, // number of input document "emit" : 4, // times of emit called "reduce" : 1, // times reduce called,note:a key that has only a single value, will not trigger the reduce "output" : 2 }, "ok" : 1, } > db.user_by_country.find() { "_id" : "CN", "value" : { "users" : [ "brodie", "davis" ], "count" : 2 } } { "_id" : "US", "value" : { "user" : "jameson", "age" : 37, "count" : 1 } } >