skip to Main Content

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?

2

Answers


  1. 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

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search