Home > Back-end >  passing the $in operator with result of previous column
passing the $in operator with result of previous column

Time:06-05

I had a document like this:

const myUser = 'e'

//Collection Selection
{
 level: [
   {
     currentUser: 'f',
     stages: [
      {
        users: ['a','b','c']
      },
      {
        users: ['b','d','e']
      }
     ]
   },
   {
     currentUser: 'g',
     stages: [
      {
        users: ['y','x','w']
      },
      {
        users: ['x','v','f']
      }
     ]
   }
 ]
}

I want to select the levels where myUser is in atleast one of the stages or is the currentUser, so I'm making a noob like query like this:

Selection.aggregate()
.addFields({myUser})
.addFields({allUsers: {   // flattening all arrays into [a,b,c,b,d,e,y,x,w,x,v,f]
  $reduce: {
     input: {
        $reduce: {
           input: $level.stages.users,
           initialValue: [],
           in: { $concatArrays: ['$$value', '$$this'] }
        },
     initialValue: [],
     in: { $concatArrays: ['$$value', '$$this'] }
     }
   }}})
match({
   $or: [
     {
       myUser: myUser
     },
     {
        myUser: {$in: '$allUsers'}
     }
    ]
 })  

and I don't know why I get a $in requires an array error message. What am I doing wrong here?

CodePudding user response:

Use $expr to compare fields in a document.

{
  $expr: {
    $in: [
      "$myUser",
      "$allUsers"
    ]
  }
}

Sample Mongo Playground


Mongoose

.match({
    $or: [
      {
        myUser: "e"
      },
      {
        $expr: {
          $in: [
            "$myUser",
            "$allUsers"
          ]
        }
      }
    ]
  }
})

CodePudding user response:

I just found out doing this works as well:

.addField({myUser})
.match({
    $or: [
      {
        myUser: "e"
      },
      {
        "level.stages.users": myUser
      }
    ]
  }
})
  • Related