mongo find and aggregate $match dont give same results

Viewed 24

I am using mongoose with node.js

"mongoose": "^6.6.1"

The query below works and returns 3 results with Model.find() as expected.

However, with aggregate and $match, it returns no results at all - WITH SAME FILTER QUERY

This is the filter query:

const filter = {
    '$and': [
        {
            '$or': [
                {
                    userId: {
                        '$in': [ '62fffec968d757addc8134fb' ]
                    },
                    sharedAt: {
                        '$exists': true
                    }
                },
                {
                    createdById: new ObjectId("62fffec968d757addc8134fb")
                }
            ]
        },
        { sharedAt: { '$exists': true } },
        {
            '$or': [
                {
                    userId: {
                        '$in': [
                            '62fffec968d757addc8138db',
                            '62fffec968d757addc813614',
                            '62fffec968d757addc81348e',
                            '62fffec968d757addc8135b7'
                        ]
                    }
                },
                {
                    createdById: {
                        '$in': [
                            '62fffec968d757addc8138db',
                            '62fffec968d757addc813614',
                            '62fffec968d757addc81348e',
                            '62fffec968d757addc8135b7'
                        ]
                    }
                }
            ]
        }
    ]
}

Why is $match returning different results than .find(...) ?

I read here that find() and aggregate $match do the same thing with a query: https://www.mongodb.com/community/forums/t/what-are-differences-between-find-and-match/34964

1 Answers

From the $match documentation:

The $match query syntax is identical to the read operation query syntax; i.e. $match does not accept raw aggregation expressions. To include aggregation expression in $match, use a $expr query expression:

You have to work with the $expr operator.

Hence your query should be as below:

{
  "$match": {
    "$expr": {
      "$and": [
        {
          "$or": [
            {
              "$in": [
                "$userId",
                [
                  "62fffec968d757addc8134fb"
                ]
              ]
            },
            {
              "$ne": [
                "$sharedAt",
                undefined
              ]
            },
            {
              "$eq": [
                "$createdById",
                new ObjectId("62fffec968d757addc8134fb")
              ]
            }
          ]
        },
        {
          "$ne": [
            "$sharedAt",
            undefined
          ]
        },
        {
          "$or": [
            {
              "$in": [
                "$userId",
                [
                  "62fffec968d757addc8138db",
                  "62fffec968d757addc813614",
                  "62fffec968d757addc81348e",
                  "62fffec968d757addc8135b7"
                ]
              ]
            },
            {
              "$in": [
                "$createdById",
                [
                  "62fffec968d757addc8138db",
                  "62fffec968d757addc813614",
                  "62fffec968d757addc81348e",
                  "62fffec968d757addc8135b7"
                ]
              ]
            }
          ]
        }
      ]
    }
  }
}
Related