I am trying to aggregrate a collection into an array of documents. This is what I want it to look like.
[
{
_id: ObjectId,
points: [
[longitude, latitude],
[longitude, latitude],
[longitude, latitude]
]
},
{
_id: DifferentObjectId,
points: [
[longitude, latitude],
[longitude, latitude],
[longitude, latitude]
]
}
]
Here is my model.
const mongoose = require('mongoose');
const workSchema = new mongoose.Schema({
fieldId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Field'
},
dayId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Day'
},
workerId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Worker'
},
contractorId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Contractor'
},
ownerId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Owner'
},
points: [{
point: {
type: {
type: String,
default: 'Point'
},
// longitude, latitude
coordinates: [Number]
},
category: {
type: String,
enum: ['entry', 'exit', 'sos', 'in', 'out']
},
createdAt: {
type: Date,
default: Date.now
}
}]
},
{
timestamps: true
});
workSchema.index({ 'points.point': '2dsphere' });
module.exports = mongoose.model('Work', workSchema);
Here is my aggregation logic.
const work = await Work.aggregate([
{
$match: {
contractorId: req.user.contractorId
}
},
{
$group: {
_id: '$fieldId',
points: {
$push: '$points.point.coordinates'
}
}
}
]);
This is what I end up getting. MAKE NOTE OF THE EXTRA LAYER OF ARRAY NESTING.
[
{
_id: ObjectId,
points: [
[
[longitude, latitude],
[longitude, latitude],
[longitude, latitude]
]
]
},
{
_id: DifferentObjectId,
points: [
[
[longitude, latitude],
[longitude, latitude],
[longitude, latitude]
]
]
}
]
I have tested grouping other fields, such as ownerId, and it works exactly as expected. I assume it has something to do with the fact that I am grouping from a field present on an array of embedded objects, but I have no clue how to fix it. Any help would be greatly appreciated!
First, you need to unwind array.
const work = await Work.aggregate([{
$match: {
contractorId: req.user.contractorId
}
},
{
$unwind: '$points'
},
{
$group: {
_id: '$fieldId',
points: {
$push: '$points.point.coordinates'
}
}
}
]);
Output will be something like
[{
_id: ObjectId,
points: [
[longitude, latitude],
[longitude, latitude],
[longitude, latitude]
]
},
{
_id: DifferentObjectId,
points: [
[longitude, latitude],
[longitude, latitude],
[longitude, latitude]
]
}
]
What you tried is correct. You can just add one more stage to flatten array of array( points
)
...
{
$addFields: {
'points': {
$reduce: {
input: '$points',
initialValue: [],
in: { $concatArrays: ["$$value", "$$this"] }
}
}
}
}
See example here to flatten array, https://docs.mongodb.com/manual/reference/operator/aggregation/reduce/#computing-a-single-reduction
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.