Home > Software engineering >  How do I find the intersection between an array of objects and a collection in MongoDB?
How do I find the intersection between an array of objects and a collection in MongoDB?

Time:10-30

Given a Mongo collection of data of the form:

// 'Entities'
{ tags: [{ a: '1', b: '1' }, { a: '2', b: '3' }] }
{ tags: [{ a: '1', b: '2' }, { a: '2', b: '3' }] }
{ tags: [{ a: '4', b: '4' }, { a: '4', b: '5' }, { a: '6', b: '7' }] }

I'd like to find all documents whose 'tag' entry has any of the following objects:

[{ a: '1', b: '1' }, { a: '4', b: '4' }]

With the example data, this would match the first and third elements:

{ tags: [{ a: '1', b: '1' }, { a: '2', b: '3' }] }
{ tags: [{ a: '4', b: '4' }, { a: '4', b: '5' }, { a: '6', b: '7' }] }

At the moment I'm doing it with a generated query (JS):

entities.find({
    $or: tags.map(tag => ({
      tags: { $elemMatch: tag },
    })
})

But this seems very inefficient, as if the number of tags I'm searching for is large I'll be essentially running hundreds of separate queries. Is there a better way?

CodePudding user response:

Perhaps nest the $or.

(I'm uncertain the shape of your data, but apparently tags is a property of approvers?)

find({
  'approvers.tags': {
    '$elemMatch': {
      $or: [
        { a: '1', b: '1' },
        { a: '4', b: '4' }
      ]
    }
  }
});

mongoplayground

CodePudding user response:

It looks like you could just use the $in operator instead, This should give better performance ( and cleaner code ) on large scale.

db.collection.find({
  approvers: {
    $in: tags
  }
})

Mongo Playground

  • Related