1

My json data will look like this

{
     "data": [
        {
            "_id": "621e139dd65883978081b6a4",
            "videoId": 29,
            "__v": 0,
            "createdAt": "2022-03-01T12:37:49.734Z",
            "updatedAt": "2022-03-04T08:47:21.481Z",
            "videoComments": [
                {
                    "comment": "happy",
                    "userId": 15,
                    "commentTime": "2022-03-01T12:37:49.734Z",
                    "userName": "user1646127068323",
                    "deletedbyowner": "FALSE",
                    "uid": "7TRmiNZ90nfyXupJIzlnBkKFnm03",
                    "_id": "621e139d8e4195079c864818",
                    "replyComments": [
                        {
                            "replyComment": "reply check",
                            "replyCommentTime": "2022-03-01T12:44:53.193Z",
                            "replyDeletedbyowner": "FALSE",
                            "_id": "621e154557fa7045e3425410"
                        }
                    ]
                },
                {
                    "comment": "happy",
                    "userId": 15,
                    "commentTime": "2022-03-01T12:38:35.116Z",
                    "userName": "user1646127068323",
                    "deletedbyowner": "FALSE",
                    "uid": "7TRmiNZ90nfyXupJIzlnBkKFnm03",
                    "_id": "621e13cb7d2f6265aa7ff7ac",
                    "replyComments": []
                },
                {
                    "comment": "happy",
                    "userId": 38,
                    "commentTime": "2022-03-01T12:39:26.064Z",
                    "userName": "user1646127068323",
                    "deletedbyowner": "FALSE",
                    "uid": "7TRmiNZ90nfyXupJIzlnBkKFnm03",
                    "_id": "621e13fe7d2f6265aa7ff7be",
                    "replyComments": [
                        {
                            "replyComment": "reply check2",
                            "replyCommentTime": "2022-03-04T08:47:21.479Z",
                            "replyDeletedbyowner": "FALSE",
                            "_id": "6221d21945208781d16377f9"
                        }
                    ]
                }
            ]
        }
    ]
}

I need to match some conditions that I mentioned below :

  1. match "videoId" == "29"

  2. then match "videoComments.deletedbyowner" == "FALSE"

  3. if I match second condition then I need to match "videoComments.replyComments.replyDeletedbyowner" == "FALSE"

  4. I need to sort the result for the user who is viewing the comment, in my case it is userId:38

So I need to show this particular comment at first.(my comment should be at first when I am viewing the comment list). I can't use unwind because my boss told me that unwind is a costly operation it will effect the app performance. so without using unwind I need to match these conditions. could you please help me out of this.

1
  • see this , its like the same question with same conditions and data, just you have 1 more condition and 1 more nested array. What do you mean sort the result for the user who is viewing the comment? Commented Mar 4, 2022 at 12:24

1 Answer 1

1

First you can filter the documents which do not meet the conditions:

db.collection.aggregate([
  {
    "$match": {
      "data.videoId": 29,
      "data.videoComments.deletedbyowner": "FALSE",
      "data.videoComments.replyComments.replyDeletedbyowner": "FALSE"
    }
  }
])

I guess after this stage the majority of documents are filtered out and $unwind should not cause any performance issue anymore.

If the data is still too big, remove the videos:

db.collection.aggregate([
  {
    "$match": {
      "data.videoId": 29,
      "data.videoComments.deletedbyowner": "FALSE",
      "data.videoComments.replyComments.replyDeletedbyowner": "FALSE"
    }
  },
  {
    $set: {
      data: {
        $filter: {
          input: "$data",
          cond: { $eq: [ "$$this.videoId",  29 ] }
        }
      }
    }
  }
])

If the data is even then still too big, remove the comments:

db.collection.aggregate([
   {
      $match: {
         "data.videoId": 29,
         "data.videoComments.deletedbyowner": "FALSE",
         "data.videoComments.replyComments.replyDeletedbyowner": "FALSE"
      }
   },
  {
    $set: {
      data: {
        $filter: {
          input: "$data",
          cond: { $eq: [ "$$this.videoId",  29 ] }
        }
      }
    }
  },
   {
      $set: {
         data: {
            $map: {
               input: "$data",
               as: "video",
               in: {
                  $filter: {
                     input: "$$video.videoComments",
                     as: "comment",
                     cond: { $eq: ["$$comment.deletedbyowner", "FALSE"] }
                  }
               }
            }
         }
      }
   }
])

I think at this stage you have to use $unwind. Otherwise you need nested $filter and $map and the aggregation pipeline is getting complicated.

Latest when you need to sort the data you must use $unwind because you cannot sort elements in an array - this will be available in upcoming MongoDB release 5.2 with $sortArray

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.