我是mongodb的新手,我正在试图弄清楚如何在下面的文档数组中计算所有返回的查询:
"impression_details" : [
{
"date" : ISODate("2014-04-24T16:35:46.051Z"),
"ip" : "::1"
},
{
"date" : ISODate("2014-04-24T16:35:53.396Z"),
"ip" : "::1"
},
{
"date" : ISODate("2014-04-25T16:22:20.314Z"),
"ip" : "::1"
}
]
我想做的是计算2014-04-24有多少(这是2)。目前,我的查询是这样的,但它不起作用:
db.banners.find({
"impression_details.date":{
"$gte": ISODate("2014-04-24T00:00:00.000Z"),
"$lte": ISODate("2014-04-24T23:59:59.000Z")
}
}).count()
不确定发生了什么事,请帮助!
谢谢。
答案 0 :(得分:0)
使用$elemMatch运营商可以做你想做的事 在您的查询中,它查找所有文件,其impression_details字段包含ISODate(" 2014-04-24T00:00:00.000Z")和ISODate(" 2014-04-24T23: 59:59.000Z&#34)。关键是,它将返回整个文档,而不是你想要的。因此,如果您只想要满足条件的子文档:
var docs = db.banners.find({
"impression_details": {
$elemMatch: {
data: {
$gte: ISODate("2014-04-24T00:00:00.000Z"),
$lte: ISODate("2014-04-24T23:59:59.000Z")
}
}
}
});
var count = 0;
docs.forEach(function(doc) {
count += doc.impression_details.length;
});
print(count);
答案 1 :(得分:0)
这里的概念是选择文档和选择子文档数组的元素之间存在明显的区别。因此,您查询中当前发生的事情正是应该发生的事情。由于文档包含至少一个符合您条件的子文档条目,因此找到该文档。
为了过滤"对于多个匹配的子文档本身的内容,则需要应用.aggregate()
方法。既然你期待计数,那么这就是你想要的:
db.banners.aggregate([
// Matching documents still makes sense
{ "$match": {
"impression_details.date":{
"$gte": ISODate("2014-04-24T00:00:00.000Z"),
"$lte": ISODate("2014-04-24T23:59:59.000Z")
}
}},
// Unwind the array
{ "$unwind": "$impression_details" },
// Actuall filter the array contents
{ "$match": {
"impression_details.date":{
"$gte": ISODate("2014-04-24T00:00:00.000Z"),
"$lte": ISODate("2014-04-24T23:59:59.000Z")
}
}},
// Group back to the normal document form and get a count
{ "$group": {
"_id": "$_id",
"impression_details": { "$push": "$impression_details" },
"count": { "$sum": 1 }
}}
])
这将为您提供一个表单,该表单只包含与数组中的查询匹配的元素,并提供匹配的条目的计数。