Reputation: 987
I'm executing a MongoDB query in ExpressJS via Mongoose.
I have documents that look like the below
{
"name": "first",
"spellings": [
"here",
"is",
"you"
],
"keyStageLevel": 4,
"spellingLevel": 2,
"__v": 0
},
{
"name": "second",
"spellings": [
"her",
"is",
"another"
],
"keyStageLevel": 2,
"spellingLevel": 3,
"__v": 0
},
{
"name": "third",
"spellings": [
"snother",
"list"
],
"keyStageLevel": 2,
"spellingLevel": 4,
"__v": 0
}
I would like to have the result of my query returned so that
1) the keyStageLevel
are in order and
2) within each keyStageLevel
the spellingLevel
are shown in order with the details of the document.
keyStageLevel 2
spellingLevel 3
name: "second",
"spellings": [
"her",
"is",
"another"
]
spellingLevel 4
name: "third",
"spellings": [
"snother",
"list"
]
keyStageLevel 4
spellingLevel 2
etc
My code currently runs
var spellings = await Spelling.aggregate([{"$group" : {_id:{keyStageLevel:"$keyStageLevel",spellingLevel:"$spellingLevel"}}} ]);
which retuns
[
{
"_id": {
"keyStageLevel": 2,
"spellingLevel": 4
}
},
{
"_id": {
"keyStageLevel": 2,
"spellingLevel": 3
}
},
{
"_id": {
"keyStageLevel": 5,
"spellingLevel": 1
}
},
{
"_id": {
"keyStageLevel": 4,
"spellingLevel": 2
}
}
]
Many thanks for any help.
Upvotes: 0
Views: 38
Reputation: 151072
What you are mostly after is using $group
to accumulate the remaining document data under each "keyStageLevel"
this is done using $push
. If you want results in specific order then you always need to $sort
, being both before and after feeding to a $group
stage:
var spellings = await Spelling.aggregate([
{ "$sort": { "keyStageLevel": 1, "spellingLevel": 1 } },
{ "$group" : {
"_id": { "keyStageLevel": "$keyStageLevel" },
"data": {
"$push": {
"spellingLevel": "$spellingLevel",
"name": "$name",
"spellings": "$spellings"
}
}
}},
{ "$sort": { "_id": 1 } }
])
The first $sort
ensures the items added via $push
are accumulated in that order, and the final ensures that the "output" is actually sorted in the desired order, as $group
will likely not always return the grouped keys in any specific order unless you instruct with such a stage.
This will give you output like:
{
"_id" : {
"keyStageLevel" : 2
},
"data" : [
{
"spellingLevel" : 3,
"name" : "second",
"spellings" : [
"her",
"is",
"another"
]
},
{
"spellingLevel" : 4,
"name" : "third",
"spellings" : [
"snother",
"list"
]
}
]
}
{
"_id" : {
"keyStageLevel" : 4
},
"data" : [
{
"spellingLevel" : 2,
"name" : "first",
"spellings" : [
"here",
"is",
"you"
]
}
]
}
Upvotes: 1