I have the following query from my Playground
Sample dataset:
[
{
"_id": {
"$oid": "637742400b359f51cb95798d"
},
"learnerId": "6377422e8a43630dcfdfd410",
"targetExam": "LON11PLUS",
"subject": "VR",
"sections": [
{
"name": "Verbal Reasoning",
"timePerSection": {
"$numberInt": "960"
},
"events": [
{
"$numberInt": "2329"
},
{
"$numberInt": "2053"
},
{
"$numberInt": "3486"
},
{
"$numberInt": "3826"
},
{
"$numberInt": "3336"
},
{
"$numberInt": "2950"
},
{
"$numberInt": "2009"
},
{
"$numberInt": "4637"
},
{
"$numberInt": "3308"
},
{
"$numberInt": "2884"
},
{
"$numberInt": "2072"
},
{
"$numberInt": "3269"
},
{
"$numberInt": "2498"
},
{
"$numberInt": "2647"
},
{
"$numberInt": "2619"
},
{
"$numberInt": "3600"
},
{
"$numberInt": "2283"
},
{
"$numberInt": "3597"
},
{
"$numberInt": "2419"
},
{
"$numberInt": "1991"
}
]
}
],
"created": "2022-11-18 08:28:48.105743",
"session": {
"id": "63778c23960b1e7e97353eea"
},
"completed": {
"$date": {
"$numberLong": "1668779074955"
}
},
"score": {
"$numberInt": "2"
}
},
{
"_id": {
"$oid": "637742590b359f51cb957990"
},
"learnerId": "6377422e8a43630dcfdfd410",
"targetExam": "LON11PLUS",
"subject": "ENG",
"sections": [
{
"name": "English",
"timePerSection": {
"$numberInt": "1500"
},
"events": [
{
"$numberInt": "779"
},
{
"$numberInt": "785"
},
{
"$numberInt": "791"
},
{
"$numberInt": "786"
},
{
"$numberInt": "784"
},
{
"$numberInt": "792"
},
{
"$numberInt": "783"
},
{
"$numberInt": "795"
},
{
"$numberInt": "781"
},
{
"$numberInt": "3041"
},
{
"$numberInt": "2053"
},
{
"$numberInt": "3497"
},
{
"$numberInt": "3840"
},
{
"$numberInt": "3023"
},
{
"$numberInt": "2285"
},
{
"$numberInt": "3022"
},
{
"$numberInt": "4644"
},
{
"$numberInt": "2477"
},
{
"$numberInt": "2472"
},
{
"$numberInt": "3338"
},
{
"$numberInt": "3270"
},
{
"$numberInt": "2018"
},
{
"$numberInt": "2288"
},
{
"$numberInt": "2260"
},
{
"$numberInt": "3603"
},
{
"$numberInt": "2463"
},
{
"$numberInt": "3600"
},
{
"$numberInt": "3312"
}
]
}
],
"created": "2022-11-18 08:29:13.804332",
"session": {
"id": "63777e1c960b1e7e97353d15"
},
"completed": {
"$date": {
"$numberLong": "1668775515232"
}
},
"score": {
"$numberInt": "6"
}
}
]
aggregate pipeline:
db.collection.aggregate([
{
$match: {
learnerId: "6377422e8a43630dcfdfd410",
targetExam: "LON11PLUS",
completed: {
$exists: true
},
},
},
{
$sort: {
completed: -1,
},
},
{
$group: {
_id: "$subject",
history: {
$push: "$$ROOT",
},
},
},
{
$group: {
_id: null,
data: {
$push: {
"k": "$_id",
"v": "$history"
},
},
},
},
{
"$replaceRoot": {
"newRoot": {
"$arrayToObject": "$data"
}
}
}
])
current output:
[
{
"ENG": [
{
"_id": ObjectId("637742590b359f51cb957990"),
"completed": ISODate("2022-11-18T12:45:15.232Z"),
"created": "2022-11-18 08:29:13.804332",
"learnerId": "6377422e8a43630dcfdfd410",
"score": 6,
"sections": [
{
"events": [
779,
785,
791,
786,
784,
792,
783,
795,
781,
3041,
2053,
3497,
3840,
3023,
2285,
3022,
4644,
2477,
2472,
3338,
3270,
2018,
2288,
2260,
3603,
2463,
3600,
3312
],
"name": "English",
"timePerSection": 1500
}
],
"session": {
"id": "63777e1c960b1e7e97353d15"
},
"subject": "ENG",
"targetExam": "LON11PLUS"
}
],
"VR": [
{
"_id": ObjectId("637742400b359f51cb95798d"),
"completed": ISODate("2022-11-18T13:44:34.955Z"),
"created": "2022-11-18 08:28:48.105743",
"learnerId": "6377422e8a43630dcfdfd410",
"score": 2,
"sections": [
{
"events": [
2329,
2053,
3486,
3826,
3336,
2950,
2009,
4637,
3308,
2884,
2072,
3269,
2498,
2647,
2619,
3600,
2283,
3597,
2419,
1991
],
"name": "Verbal Reasoning",
"timePerSection": 960
}
],
"session": {
"id": "63778c23960b1e7e97353eea"
},
"subject": "VR",
"targetExam": "LON11PLUS"
}
]
}
]
I get an array with a single object, while the way I have structured the query, there should always be a single object.
How can I get this single object as root rather than nested in an array?
CodePudding user response:
If I understand the question correctly, you want the aggregate
method to return a single object and not an Array that contains one object.
If that understanding is correct, then it is worth mentioning that aggregate
method always returns a cursor (ref) and as a rule of thumb in MongoDB, anything that returns a cursor (find, aggregate), will always return a list a.k.a. an array.
My apologies, if you did not want to hear this, but you cannot have an aggregation returning a single object instead of an array having a single object.
Your best bet here is to just hardcode the 0'th position to get the document. Something like:
let result = await db.users.aggregate([...]);
let my_user_aggregated_data = result[0];
I hope it clarifies.