我在和MongoDb打架
我有一个文档集合,其中单个文档的结构如下
{
"_id": { "$oid": "588a931d5c98fe0f3f84d93f" },
"name": "Michele",
"type": "F",
"category": "G",
"meta":{
"code": "113835667",
"updated": {"$date": "2017-02-07T00:00:00.000Z"},
"since": {"$date": "2013-11-07T23:00:00.000Z"}
},
"data": [
{
"date": {"$date": "2013-11-07T23:00:00.000Z"},
"close": 12.23
}
... // removed
{
"date": {"$date": "2017-02-07T00:00:00.000Z"},
"close": 15.22
}
]
}我需要做的是返回具有匹配日期的文档,但是从数据数组中过滤掉_id属性不在指定时间范围内的文档。
这就是我从现在开始的尝试
let id; //[DocumentId]
let from; //[Date]
let to; //[Date]
collection.aggregate([
{ $match: { _id: { $eq: id } } },
{ $unwind: '$data' },
{ $match: { 'data.date': { $gte: from, $lte: to } } },
{ $group: { _id: '$_id',
data: { $push: { date:'$data.date', close: '$data.close' } } } }
], ...);这种方法的问题是,我返回的文档只包含_id和数据属性,数据过滤结果是可以的,而我需要返回完整的可用属性集。
非常感谢您的建议!
发布于 2017-02-10 14:26:45
如果你可以升级到Mongo 3.4 (最新的稳定版本),这可以做得很好:
db.collection.aggregate([
//Pre-filter to have data arrays with at least one matching date
{$match: {_id: id, 'data.date': {$gte: from, $lte: to}}},
//Filter the items array
{
$addFields: {
'items': {
$filter: {
input: '$data', as: 'item', cond: {
$and: [
{$gte: ["$$item.date", from]},
{$lte: ["$$item.date", to]}
]
}
}
}
}
}
]);
如果你必须保持mongo 3.2,我唯一能想到的就是像这样使用$ROOT:
db.collection.aggregate([
{$match: {_id: id, 'data.date': {$gte: from, $lte: to}}},
{
$project: {
'filteredData': {
$filter: {
input: '$data', as: 'item', cond: {
$and: [
{$gte: ["$$item.date", from]},
{$lte: ["$$item.date", to]}
]
}
}
},
'originalDocument': '$$ROOT'
}
}
]);
结果对象将具有originalDocument和filteredData属性,您需要在服务器代码中处理它们(实际上是一个循环)。
https://stackoverflow.com/questions/42110650
复制相似问题