I have a collection like this:
[
{
"name": "Banana",
"variants": [
{
"color": "blue",
"props": []
},
{
"color": "green",
"props": [
{
"uid": 1,
"grade": 3
},
{
"uid": 3,
"grade": 2
}
]
}
]
}
]
For each document in the query result, the variants array should be sorted by the condition "props is empty" vs. "props is not empty", listing variants containing props first. In the example, the variant with color green should be first since it has props, followed by the variant with color blue since it does not contain any props.
Desired outcome:
[
{
"name": "Banana",
"variants": [
{
"color": "green",
"props": [
{
"grade": 3,
"uid": 1
},
{
"grade": 2,
"uid": 3
}
]
},
{
"color": "blue",
"props": []
}
]
}
]
In the documentation there are only examples to sort by document-field and a sort-direction, unfortunately I don’t see an option to sort by a custom evaluation.
Thanks for your help!
>Solution :
You can define your sorting criteria by adding a length field into each object in the variants array before performing $sortArray.
Then remove the variants.length field.
This will guarantee that the element with the props field is an empty array is placed at the last.
db.collection.aggregate([
{
$set: {
variants: {
$sortArray: {
input: {
$map: {
input: "$variants",
in: {
$mergeObjects: [
"$$this",
{
length: {
$size: "$$this.props"
}
}
]
}
}
},
sortBy: {
length: -1
}
}
}
}
},
{
$unset: [
"variants.length"
]
}
])