Reputation: 23
I have documents in MongoDB, like so:
{
"_id" : ObjectId("5a748c8b178227d602ec9ce8"),
"dateHour" : ISODate("2018-02-02T16:00:00.000Z"),
"data" : [
{
"date" : ISODate("2018-02-02T16:06:35.033Z"),
"cap" : 437105726836.0
},
{
"date" : ISODate("2018-02-02T16:09:25.127Z"),
"cap" : 437316498502.0
},
...
]
}
Using aggregate method (in NodeJS):
db.getCollection('hourly').aggregate([
{$match: {}},
{$unwind: "$data"},
{$project: {_id: 0, date: "$data.date", cap: "$data.cap" } }
])
I get output like:
[
{
"date" : ISODate("2018-02-02T16:06:35.033Z"),
"cap" : 437105726836.0
},
{
"date" : ISODate("2018-02-02T16:09:25.127Z"),
"cap" : 437316498502.0
}
]
QUESTION: What is the most effective way to get output like so:
[
[ISODate("2018-02-02T16:06:35.033Z"), 437105726836.0],
[ISODate("2018-02-02T16:09:25.127Z"), 437316498502.0]
]
?
I can simply add .map(function(item) {return [item.date, item.cap]})
but is this most effective way when working with huge amount of data?
Upvotes: 2
Views: 5180
Reputation: 12817
try $project
with $map
or $reduce
$map
db.col.aggregate(
[
{$project : {
_id : 0,
data : {$map : {input : "$data", as : "d", in : ["$$d.date", "$$d.cap"]}}
}
}
]
)
$reduce
db.col.aggregate(
[
{$project : {
_id : 0,
data : {$reduce : {input : "$data", initialValue : [], in : {$concatArrays : ["$$value", [["$$this.date", "$$this.cap"]]]}}}
}
}
]
).pretty()
output
{
"data" : [
[
ISODate("2018-02-02T16:06:35.033Z"),
437105726836
],
[
ISODate("2018-02-02T16:09:25.127Z"),
437316498502
]
]
}
Upvotes: 2
Reputation: 592
It's in the projection. Try this:
db.getCollection('hourly').aggregate([
{$match: {}},
{$unwind: "$data"},
{$project: {_id: 0, date: ["$data.date", "$data.cap"] } }
]);
Just in case my syntax is a little off, here is MongoDb documentation to project a new array.
I don't see why you need aggregate.
Why not:
db.getCollection('hourly').find({}, {data: 1}, (err, results) => {
// manage results here.
});
Upvotes: 0
Reputation: 14436
The root has to be a document, proof:
db.test.aggregate([
{$unwind: "$data"},
{ $replaceRoot: { newRoot: ["$data.date", "$data.cap"] } }
]);
assert: command failed: {
"ok" : 0,
"errmsg" : "'newRoot' expression must evaluate to an object, but resulting value was: [null, null]. Type of resulting value: 'array'. Input document: {date: 2018-02-02T16:06:35.033Z, cap: 4.37106e+11}",
"code" : 40228,
"codeName" : "Location40228"
} : aggregate failed
You could, however, project it into an array within a document:
> db.test.aggregate([
... {$unwind: "$data"},
... { $replaceRoot: { newRoot: {a:["$data.date", "$data.cap"] } }}
... ])
{ "a" : [ ISODate("2018-02-02T16:06:35.033Z"), 437105726836 ] }
{ "a" : [ ISODate("2018-02-02T16:09:25.127Z"), 437316498502 ] }
Upvotes: 0