Warix3
Warix3

Reputation: 101

MongoDB - How to use $expr inside of $elemMatch

Here is my query:

db.collection('guilds').aggregate([
    {
        $match: { users: { $elemMatch: {
            $and: [
                { 'registeredAt': { $exists: false } },
                { $expr: {
                    $gt: [
                        { $divide: [
                            { $subtract: [
                                new Date(),
                                '$joinedAt'] },
                            1000 * 60 * 60 * 24] },
                        1] } }],
        } } },
    },
])

and here is my data:

mongodbdata

I'm getting this error when I try to run the aggregation:

MongoError: $expr can only be applied to the top-level document

How can I solve it? I've seen this question but I feel like it's not the best answer: Also if there is another way to achieve the same result I'd appreciate that too

Upvotes: 1

Views: 999

Answers (1)

Joe
Joe

Reputation: 28376

The $expr operator uses aggregation operations instead of query operations. $elemMatch is a query operator, which doesn't work with $expr.

For this use case, calculating the date on the client side will reduce the work required of the database, and permit the query planner to use an index on 'joinedAt' (if one exists):

let oneDayAgo = new Date(new Date() - (1000 * 60 * 60 * 24]))
db.collection('guilds').aggregate([
    {
        $match: { users: { $elemMatch: {
                       'registeredAt': { $exists: false },
                       'joinedAt': {$gte: oneDayAgo}
                
        } } },
    },
])

Upvotes: 1

Related Questions