I have several hundred records in this format:
{
"_id" : ObjectId( "51ac1356c59151b66c0c9b6b" ),
"name" : "SomeString",
"subject" : [
"_id" : ObjectId( "51ac1356c59151b66c0c912d" ),
"subjectName": "SomeString",
"prerequisite": [ "subject1", "subject2"]
]
}
Here's what the data looks like:
[
{
"_id": "123456",
"name": "StudentB",
"subject": [
{
"_id": "78901",
"subjectName": "Politics 101",
"prerequisite": []
},
{
"_id": "10987",
"subjectName": "Geography 500",
"prerequisite": []
},
{
"_id": "78901",
"subjectName": "Science 500",
"prerequisite": [
"Science 204",
"Math 100"
]
},
{
"_id": "54321",
"subjectName": "Maths 600",
"prerequisite": [
"Science 400",
"Math 400"
]
}
]
},
{
"_id": "654321",
"name": "StudentA",
"subject": [
{
"_id": "78901",
"subjectName": "Music 101",
"prerequisite": []
},
{
"_id": "78901",
"subjectName": "History 500",
"prerequisite": [
"History 200"
]
},
{
"_id": "54321",
"subjectName": "Maths 600",
"prerequisite": [
"Science 400",
"Math 400"
]
},
{
"_id": "10987",
"subjectName": "Geography 500",
"prerequisite": []
}
]
}
]
I am trying to construct a query to get the below result:
[
{
"_id": "654321",
"name": "StudentA",
"subject": [
{
"_id": "78901",
"subjectName": "History 500",
"prerequisite": [
"History 200"
]
},
{
"_id": "54321",
"subjectName": "Maths 600",
"prerequisite": [
"Science 400",
"Math 400"
]
},
{
"_id": "10987",
"subjectName": "Geography 500",
"prerequisite": []
},
{
"_id": "78901",
"subjectName": "Music 101",
"prerequisite": []
}
]
},
{
"_id": "123456",
"name": "StudentB",
"subject": [
{
"_id": "54321",
"subjectName": "Maths 600",
"prerequisite": [
"Science 400",
"Math 400"
]
},
{
"_id": "78901",
"subjectName": "Science 500",
"prerequisite": [
"Science 204",
"Math 100"
]
},
{
"_id": "10987",
"subjectName": "Geography 500",
"prerequisite": []
},
{
"_id": "78901",
"subjectName": "Politics 101",
"prerequisite": []
}
]
}
]
Here's what I have tried so far:
studentDetails.aggregate([
{
$project: {
'_id': 1,
'name': 1,
'subject.subjectName': 1,
'subject.prerequisite': 1
}
},
{
$unwind: '$subject'
},
{
$sort: {
'subject.prerequisite': -1
}
},
{
$group: {
_id: '$_id',
subject: { $push: '$subject' },
name: { $first: '$name' },
}
}
]);
The above aggregation returns the subdocuments sorted in reverse alphabetical order where the prerequisites are ordered from ZA and the empty arrays are at the end of the list.
I need to sort the documents in the DB according to:
It is totally difficult to do both sorting together, because
subject.subjectName: 1
it will sort ascending ordersubject.prerequisite: -1
it will sort descending order but it reset above sortYou can try this experiment,
$unwind: ... , // skipped
subjectName
ascending order {
$sort: {
"subject.subjectName": 1
}
},
viewOrder
in subject
arrayprerequisite
array size greater then 0 then set 1 otherwise 0 {
$addFields: {
"subject.viewOrder": {
$cond: {
if: {
$size: "$subject.prerequisite"
},
then: 1,
else: 0
}
}
}
},
viewOrder
descending order {
$sort: {
"subject.viewOrder": -1
}
},
viewOrder
field {
$project: {
"subject.viewOrder": 0
}
},
$group: ... , // skipped
name
ascending order {
$sort: {
name: 1
}
}
Here you have achieved your desired result.
Playground: https://mongoplayground.net/p/syg2w_d0j_b
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.