Home > Enterprise >  Could there be a (unique) workaround for duplicate "$or" keys when working with boolean lo
Could there be a (unique) workaround for duplicate "$or" keys when working with boolean lo

Time:11-22

When I asked a question earlier about querying in MongoDB resolved the respective issue, but another question stemmed from the original idea.

Under similar conditions, suppose that I'm trying to query:

    Example: {
    "AttributeA": type,
    "AttributeB": type,
    "AttributeC": type,
    "AttributeD": type
    etc...
    }

But I want to find all elements given the conditions where:

(Attribute A matches criteria1 or Attribute B matches criteria2) and (Attribute C matches criteria3 or Attribute D matches criteria4 or Attribute E matches criteria5)

The $in operator only tracks an $or conditional given that the attributes are the same (eg. referring to previous question of AttributeC matching criteria 3, 4, or 5). So the general layout in this new query would be more like:

    db.Example.find({
      $or:[ {AttrA : "criteria1"}, {AttrB : "criteria2"}],
      $or:[ {AttrC : "criteria3"}, {AttrD : "criteria4"}, {AttrE : "criteria5"} ]
    })

But under the conditions above it seems impossible without a duplicate "$or" operator unless I do some boolean algebra and separate it into:

((A B)*(C D E) = AC AD AE BC BD BE) aka AttrA matches ... and AttrC matches ... or AttrA matches ... and AttrD matches ... or ... AttrB matches ... and AttrE matches ...

meaning that the format would look like

    db.Example.find({
    $or:[
          $and:[{AttrA : "criteria1"}, {AttrC : "criteria3"}],
          $and:[{AttrA : "criteria1"}, {AttrD : "criteria4"}],
          ...,
          $and:[{AttrB : "criteria2"}, {AttrE : "criteria5"}
        ]
    })

Though I'm not even sure if the mongoDB system allows for duplicate "$and"s either. Could there be an easier way or am I overcomplicating the conditional queries?

CodePudding user response:

There is no need to manually distribute the conditions here. You must use the $and explicitly rather than implying on the implicit one:

db.Example.find({
  $and: [
    { $or:[ {AttrA : "criteria1"}, {AttrB : "criteria2"}] },
    { $or:[ {AttrC : "criteria3"}, {AttrD : "criteria4"}, {AttrE : "criteria5"} ] }
  ]
})

Playground example here. This is covered in the documentation here.

The general problem that is encountered, at least with Javascript that includes the shell, is that duplicate field names are not supported. Consider this example using Node directly:

$ node
Welcome to Node.js v16.17.0.
Type ".help" for more information.
> let x = { x: 123, y: 456, x: 789 }
undefined
> x
{ x: 789, y: 456 }
>
  • Related