Home > Blockchain >  How to limit MongoDB results with condition after the aggregation stage
How to limit MongoDB results with condition after the aggregation stage

Time:09-17

I would like to fetch results based on a condition after the aggregation stage. My code gives me an array of 4 results instead of 3. The Logic is a user swipes and the data stored in a collection. The collection stores the first swipe and if the other user swipes an existing entry the collection document is updated instead of a new insert depending on who swiped first thus the $or queries. This works fine until I change an existing user's hookup status to false on the users collection. Resulting to an array of length 4 instead of 3. The extra array is created from the $or query and has user_two only.

Swipe Collection _id(ObjectID) - user_one(string) - user_two(string) - status_one(number) - status_two(number)

User Collection _id(ObjectID) - user_name(string) - hookups(boolean)

const fetchHookups = (req, res, next) => {
var query = {
        $or: [
             { user_one: ObjectId(req.body._id)},
             { user_two: ObjectId(req.body._id) },
            ]
        }
    
Swipe.aggregate([{
    $match: query
    },
    {
      $lookup: {
        from: 'users',
        let: { user_one: '$user_one', hookupstatus: true },
        pipeline: [{
        $match: {
        $expr: {
            $and: [
                { $eq: ["$_id", '$$user_one'] },
                { $eq: ["$hookups", '$$hookupstatus'] },
                ],
            }
        }
        }],
        as: "userone"
        }
    },
    {
      $unwind: {
        path: "$userone",
        preserveNullAndEmptyArrays: true,
        },
    },
    {
      $lookup: {
        from: 'users',
        let: { user_two: '$user_two', hookupstatus: true },
        pipeline: [{
        $match: {
        $expr: {
            $and: [
                { $eq: ["$_id", '$$user_two'] },
                { $eq: ["$hookups", '$$hookupstatus'] },
                ],
            }
        }
        }],
        as: "usertwo"
        }
    },
    {
      $unwind: {
        path: "$usertwo",
        preserveNullAndEmptyArrays: true,
        },
    },

    {
        $sort: {
            _id: -1
            }
        }
    ]).exec(function(error, response) {
        if (error) {
            console.log(error)
            } else {
                res.json(response)
                }
    })
}

CodePudding user response:

I figured it out thanks to @Thomas and here's how:

{
 $redact: {
  $cond: [{
    $eq: ["$userone.hookups", true],
    $eq: ["$usertwo.hookups", true],
    },
    "$$KEEP",
    "$$PRUNE"
    ]
   }
},

CodePudding user response:

I've not tried it, but the $redact operator sounds like it does what you want.

Here is a rather old but well written example: Find documents whose array field contains at least n elements of a given array

  • Related