Home > database >  MongoDB aggregate filter returns null
MongoDB aggregate filter returns null

Time:09-25

In MongoDB, I have a messages' collection (find it below):

I'm interested in querying the parent document by id, and say filtering contactedNumberMessages to include only incoming messages (those having direction "in") so I wrote the following code with Mongoose, however contactedNumberMessages is null in the returned data, any clue as to why I'm getting null? Thank you

Messages.aggregate([
    {
      $match: {
        _id: id
      }
    },
    {
      $project: {
        messaging: {
          ourNumber: 1,
          messages: {
            contact: 1,
            contactedNumberMessages: {
              $filter: {
                input: "$contactedNumberMessages",
                as: "message",
                cond: {
                  $eq: ["$$message.direction", "out"]
                }
              }
            }
          }
        }
      }
    }
  ]);
{
  "_id": {
    "$oid": "612f4e32aa56064f1608c2eb"
  },
  "messaging": [
    {
      "ourNumber": " 15123568549",
      "messages": [
        {
          "contact": " 21629000111",
          "contactedNumberMessages": [
            {
              "direction": "out",
              "content": "Hello!",
              "when": {
                "$date": "2021-09-23T23:00:00.000Z"
              },
              "nature": "SMS"
            },
            {
              "direction": "in",
              "content": "Hi!",
              "when": {
                "$date": "2021-09-23T23:00:00.000Z"
              },
              "nature": "SMS"
            }
          ]
        }
      ]
    }
  ]
}

CodePudding user response:

pls refer to example here: https://mongoplayground.net/p/9toRoa_5IE9

you should use something like below in aggregation:

[{$match: {
  _id: ObjectId('612f4e32aa56064f1608c2eb')
}}, {$unwind: {
  path: '$messaging',
}}, {$unwind: {
  path: '$messaging.messages',
}}, {$project: {
        messaging: {
    ourNumber: 1,
    messages: {
      contact: 1,
      contactedNumberMessages: {
        $filter: {
          input: "$messaging.messages.contactedNumberMessages",
          as: "message",
          cond: {
            $eq: ["$$message.direction", "out"]
          }
        }
      }
    }
  }
}}]

As you have nested array within array and sub array that filter stage was not getting correct output, i have added unwind to get the normal array for field:messaging.messages.contactedNumberMessages

if needed you can again do groupby to ensure you get document in expected format as after unwind it will create multiple documents in aggregation for each documents in array which in unwinded.

  • Related