I have following result data which is not properly sorted according to my needs
[
{
"_id": "defmongodb_objectId",
"categories": [
{
"category": "123mongodb_objectId" //reference Id
"positionAccordingToCategory": 2,
},
{
"category": "789mongodb_objectId" //reference Id
"positionAccordingToCategory": 1,
},
],
},
{
"_id": "abcmongodb_objectId",
"categories": [
{
"category": "789mongodb_objectId" //reference Id
"positionAccordingToCategory": 2,
},
],
},
{
"_id": "0mongodb_objectId",
"categories": [
{
"category": "789mongodb_objectId" //reference Id
"positionAccordingToCategory": 0,
},
],
},
]
EXPECTED RESULT
[
{
"_id": "abcmongodb_objectId",
"categories": [
{
"category": "789mongodb_objectId" //reference Id
"positionAccordingToCategory": 2,
},
],
},
{
"_id": "defmongodb_objectId",
"categories": [
{
"category": "123mongodb_objectId" //reference Id
"positionAccordingToCategory": 2,
},
{
"category": "789mongodb_objectId" //reference Id
"positionAccordingToCategory": 1,
},
],
},
{
"_id": "0mongodb_objectId",
"categories": [
{
"category": "789mongodb_objectId" //reference Id
"positionAccordingToCategory": 0,
},
],
},
]
I want to sort the result by that positionAccordingToCategory
which the given id matches with the category
.
EXAMPLE
The id provided is 789mongodb_objectId
, and it is the second element of the categories
array, so I want the result by the positionAccordingToCategory
of category
, 789mongodb_objectId
.
ISSUE
The issue is that it sorts the result by matching the **first** element of the categories array
no matter what category id is provided.
Basically I want to show the same document at different positions in different categories ,according to category.
MY CURRENT QUERY
await this.myModel
.find({
// other filters
categories: { $elemMatch: { category: 'category._id '} },
})
.sort({ 'categories.positionAccordingToCategory': -1 })
This query only works when there's only single object element in categories
It's not
like query throws
any error
when there are more than one element, but the issue is it disturbs
the order
in the particular category list. As in the above example the element should be visible at 1st index but instead it goes to 2nd index, and if there are another element of that category with the same index as 2 than it moves to 3rd index
YOU CAN PROVIDE ANY AGGREGATION QUERY SOLUTION WHICH I WILL USE AT THE LAST OPTION, BUT I WON'T PREFER ANY AGGREGATION HERE.
This is just one way to do this using an aggregation. There must be infinite possibilities, but this one's tested and it works (I've change the category ids into names, but it's the same concept).
Notice that I've added an extra first $match
stage that you might not need, so feel free to remove it, and the last $project
stage is just clean up, so you might be able to get rid of that one as well.
[ { '$match': { 'categories': { '$elemMatch': { 'category': 'category_789' } } } }, { '$project': { '_id': 1, 'categories': 1, 'sortCategory': { '$filter': { 'input': '$categories', 'as': 'c', 'cond': { '$eq': [ '$$c.category', 'category_789' ] } } } } }, { '$sort': { 'sortCategory.positionAccordingToCategory': -1 } }, { '$project': { '_id': 1, 'categories': 1 } } ]