I'm fighting with MongoDb
I have a collection of documents with single document structured as follows
{
"_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
}
]
}
What i need to achieve is returning the document with matching _id but filter out from the data array the documents with date property not inside a specified time range.
this is what I've attempted since now
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' } } } }
], ...);
the problem with this approach is that the document I return only contains _id and data properties [data filtering result is ok] while I need to return the full set of available properties.
suggestions are greatly appreciated!
If you could upgrade to Mongo 3.4 (the latest stable release) it could be done nicely:
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]}
]
}
}
}
}
}
]);
If you have to keep mongo 3.2 the only thing I can think of is to use $ROOT like this:
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'
}
}
]);
The resulting objects will have originalDocument and filteredData as properties, and you'll need to process them in your server code (one loop in fact).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With