一、简介
我们上一篇介绍了db.collection.find()可以实现根据条件查询和指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段,我们今天介绍了对数组和内嵌文档的查询操作,尤其是对$elemMatch 同样可以用在find方法的第二个参数来限制返回数组内的元素,只返回我们需要的文档的介绍。我们经常在查询条件查询内嵌文档数组时,只需要返回主文档并返回内嵌文档数组中我们只需要的值,而不是把内嵌文档的数组都返回。
二、对数组根据条件查询
$all、$size、$slice、$elemMatch
(1)$all查找数组中包含指定的值的文档
语法:
{ field:{ $all: [ , ... ]}
例子:
db.orders.find({"books":{$all:["java","mongo"]}})
查找books包含java、mongo的文档数据
(2)$size 查找数组大小等于指定值的文档
语法:
{field: {$size: number } }
例子:
>db.orders.find({"books":{$size:2}})
(3)$slice查询数组中指定返回元素的个数
语法:
>db.collect.find({},{field:{$slice: number }})
number 说明:
为正数表示返回前面指定的值的个数:例如1 返回数组第一个
为负数表示返回倒数指定的值的个数:例如-1返回数组倒数第一个
例子:
>db.orders.find({"onumber":{$in:["008","009"]}},{books:{$slice:1}})
1)$slice可以查询数组中第几个到第几个
语法:
>db.collect.find({},{field:{$slice:[ number1, number2] }})
跳过数组的number1个位置然后返回number2个数
number1说明:
为正数表示跳到指定值的数组个数:例如2 跳到数组第3个
为负数表示跳到指定值的数组倒数个数:例如-2跳到到数组倒数第3个
例子:
>db.orders.find({"onumber":{$in:["008","009"]}},{books:{$slice:[1,1]}})
跳过books数组第一个元素,现在到数组第二个元素,并返回1个元素
三、对数组内嵌文档查询
我们先保存数据
db. orders.insert([
{
"onumber" : "001",
"date" : "2015-07-02",
"cname" : "zcy1",
"items" :[ {
"ino" : "001",
"quantity" :2,
"price" : 4.0
},{
"ino" : "002",
"quantity" : 4,
"price" : 6.0
}
]
},{
"onumber" : "002",
"date" : "2015-07-02",
"cname" : "zcy2",
"items" :[ {
"ino" : "001",
"quantity" :2,
"price" : 4.0
},{
"ino" : "002",
"quantity" :6,
"price" : 6.0
}
]
}
])
(1)$elemMatch 文档包含有一个元素是数组,那么$elemMatch可以匹配内数组内的元素并返回文档数据
语法:
>{field:{$elemMatch:{ field1:value1, field2:value2,………}}}
例子:
>db.orders.find({"items":{$elemMatch:{"quantity":2}}})
返回quantity为2的文档
也可以这样查询db.orders.find({"items.quantity":2})
(2) $elemMatch可以带多个查询条件
例子:
>db.orders.find({"items":{$elemMatch:{"quantity":4,"ino":"002"}}})
我们查询数组中的quantity等于4并且ino等于002,但是我们就想返回数组中的quantity等于4并且ino等于002的这个文档,并不想把ino等于001等这些无关的文档返回。
(3)$elemMatch 同样可以用在find方法的第二个参数来限制返回数组内的元素,只返回我们需要的文档
例子:
db.orders.find({"onumber":"001"},{"items":{$elemMatch:{"quantity":4,"ino":"002"}},"cname":1,"date":1,"onumber":1})
我们只返回quantity等于4并且ino等于002的文档,无关的文档没有返回,方便我们处理数据,这样也可以节省传输数据量,减少了内存消耗,提高了性能,在数据大时,性能很明显的。