Home > database >  how can i sort data with a array element in mongodb without using unwind
how can i sort data with a array element in mongodb without using unwind

Time:05-29

this is my sample data in this I have a userId and a array "watchHistory", "watchHistory" array contains the list of videos that is watched by the user :

    {
        "_id": "62821344445c30b35b441f11",
        "userId": 579,
        "__v": 0,
        "watchHistory": [
            {
                "seenTime": "2022-05-23T08:29:19.781Z",
                "videoId": 789456,
                "uploadTime": "2022-03-29T12:33:35.312Z",
                "description": "Biography of Indira Gandhi",
                "speaker": "andrews",
                "title": "Indira Gandhi",
                "_id": "628b45df775e3973f3a670ec"
            },
            {
                "seenTime": "2022-05-23T08:29:39.867Z",
                "videoId": 789455,
                "uploadTime": "2022-03-31T07:37:39.712Z",
                "description": "What are some healthy food habits to stay healthy",
                "speaker": "morris",
                "title": "Healthy Food Habits",
                "_id": "628b45f3775e3973f3a670"
            },
            
        ]
    }

I need to match the userId and after that i need to sort it with "watchHistory.seenTime", seenTime field indicates when the user saw the video. so i need to sort like the last watched video should come first in the list. I don't have permission to use unwind so can any one help me from this. Thank you.

CodePudding user response:

If you are using MongoDB version 5.2 and above, you can use $sortArray operator in an aggregation pipeline. Your pipeline should look something like this:

db.collection.aggregate(
  [
    {"$match": 
      { _id: '62821344445c30b35b441f11' }
    },
    {
      "$project": {
        _id: 1,
        "userId": 1,
        "__v": 1,
        "watchHistory": {
          "$sortArray": { input: "$watchHistory", sortBy: { seenTime: -1 }}
        }
      }
    }
  ]
);

Please modify the filter for "$match" stage, according to the key and value you need to filter on. Here's the link to the documentation.

Without using unwind, it's not possible to do it via an aggregation pipeline, but you can use update method and $push operator, as a workaround like this:

db.collection.update({
  _id: "62821344445c30b35b441f11"
},
{
  $push: {
    watchHistory: {
      "$each": [],
      "$sort": {
        seenTime: -1
      },
    }
  }
})

Please see the working example here

  • Related