Search code examples
databasemongodbaggregation-frameworknosql-aggregation

mongo aggregation $lookup with arrays


I have a structure like this

unions {              // collection
  members {           // array
    instanceId        // some id
    ...
  }
  ...
}

In documents, I have ids prop (array) I need to lookup all unions that have at least one id from ids (basically $in)

The problem is that it doesn't work

First I wanted to try this variant

{
  from: 'unions',
  let: { instanceIds: '$ids'  },
  as: 'unions',
  pipeline: [
    {
      $match: { 'members.instanceId': { $in: '$$instanceIds' } },
    },
  ],
}

But we can't use aggregation variables here. For that, we need to use $expr

{
  from: 'unions',
  let: { instanceIds: '$ids'  },
  as: 'unions',
  pipeline: [
    {
      $match: {
        $expr: {
          $in: ['$members.instanceId', '$$instanceIds']
        }
      },
    },
  ],
}

But then it returns 0 documents. The instanceIds array is not empty, I've checked it. Also, if I paste an array with values in the example without $expr then it returns the right values. So most likely the problem is how I build this $lookup.


Solution

  • use { $ne: [{ $setIntersection: ['$members.instanceId', '$$instanceIds'] }, []] }

    {
      from: 'unions',
      let: { instanceIds: '$ids'  },
      as: 'unions',
      pipeline: [
        {
          $match: {
            $expr: {
              cond: { $ne: [{ $setIntersection: ['$members.instanceId', '$$instanceIds'] }, []] },
            },
          },
        },
      ],
    }