我有一个包含以下文件的集合。
{
"id":1,
"url":"mysite.com",
"views":
[
{"ip":"1.1.1.1","date":ISODate("2015-03-13T13:34:40.0Z")},
{"ip":"2.2.2.2","date":ISODate("2015-03-13T13:34:40.0Z")},
{"ip":"1.1.1.1","date":ISODate("2015-02-13T13:34:40.0Z")},
{"ip":"1.1.1.1","date":ISODate("2015-02-13T13:34:40.0Z")}
]
},
{
"id":2,
"url":"mysite2.com",
"views":
[
{"ip":"1.1.1.1","date":ISODate("2015-01-13T13:34:40.0Z")},
{"ip":"2.2.2.2","date":ISODate("2015-01-13T13:34:40.0Z")},
{"ip":"1.1.1.1","date":ISODate("2015-02-13T13:34:40.0Z")},
{"ip":"1.1.1.1","date":ISODate("2015-02-13T13:34:40.0Z")}
]
}
如何获取id = 1
和date(Y-m) = 2015-02
的文档?
答案 0 :(得分:0)
您可以使用aggregation pipeline operators。以下内容将返回views
数组中符合条件的所有子文档。
$match
使用给定的id
过滤选择的文档
$unwind
views数组。在您的第一个$project
阶段,使用$year
运算符返回日期年份和$month
日期的月份。接下来,使用month
按year
和$match
过滤您的文档。 _id
{} {}} {} {{}} {{}} {} {{}}
$project
<强>结果强>
db.collection.aggregate(
[
{'$match': {'id': 1}},
{'$unwind': '$views'},
{'$project': {
'id': 1,
'year': {'$year': '$views.date'},
'month': {'$month': '$views.date'},
'url': 1, 'views': 1
}
},
{'$match': {'year': 2015, 'month': 2}},
{'$group': {
'_id': '$id',
'url': {'$first': 'url'},
'views': {'$push': '$views'}
}
},
{'$project': {'id': '$_id', 'views': 1, 'url': 1, '_id': 0}}
]
)
答案 1 :(得分:0)
要获取满足上述条件的特定{
"url" : "url",
"views" : [
{
"ip" : "1.1.1.1",
"date" : ISODate("2015-02-13T13:34:40Z")
},
{
"ip" : "1.1.1.1",
"date" : ISODate("2015-02-13T13:34:40Z")
}
],
"id" : 1
}
数组元素(子文档),请使用$group
投影运算符,如下所示:
"views"
返回:
var start = new Date(2015, 0, 31, 23, 59, 59),
end = new Date(2015, 2, 1);
db.test.find(
{
id: 1,
"views.date": { "$gt": start, "$lt": end}
},
{
"id": 1,
"views": {
"$elemMatch": {
"date": { "$gt": start, "$lt": end}
}
}
});
如果您只想返回整个文档,请使用不带$elemMatch
投影的日期范围查询,如下所示:
/* 0 */
{
"_id" : ObjectId("555089bf9cd8fa39c7971e33"),
"id" : 1,
"views" : [
{
"ip" : "1.1.1.1",
"date" : ISODate("2015-02-13T13:34:40.000Z")
}
]
}
上面的查询将返回符合上述条件的整个文档,包括as = ll子文档:
var start = new Date(2015, 0, 31, 23, 59, 59),
end = new Date(2015, 2, 1);
db.test.find({id: 1, "views.date": { "$gt": start, "$lt": end}})