1

In some documents I have a property with a complex structure like:

{
  content: {
    foo: {
      id: 1,
      name: 'First',
      active: true 
    },
    bar: {
      id: 2,
      name: 'Second',
      active: false 
    },
    baz: {
      id: 3,
      name: 'Third',
      active: true 
    },
}

I'm trying to make a query that can find all documents with a given value in the field name across the different second level objects foo, bar, baz

I guess that a solution could be:

db.getCollection('mycollection').find({ $or: [
    {'content.foo.name': 'First'},
    {'content.bar.name': 'First'},
    {'content.baz.name': 'First'}
]})

But a I want to do it dynamic, with no need to specify key names of nested fields, nether repeat the value to find in every line.

If some Regexp on field name were available , a solution could be:

db.getCollection('mycollection').find({'content.*.name': 'First'}) // Match
db.getCollection('mycollection').find({'content.*.name': 'Third'}) // Match
db.getCollection('mycollection').find({'content.*.name': 'Fourth'}) // Doesn't match

Is there any way to do it?

1 Answer 1

1

I would say this is a bad schema if you don't know your keys in advance. Personally I'd recommend to change this to an array structure.

Regardless what you can do is use the aggregation $objectToArray operator, then query that newly created object. Mind you this approach requires a collection scan each time you execute a query.

db.collection.aggregate([
  {
    $addFields: {
      arr: {
        "$objectToArray": "$content"
      }
    }
  },
  {
    $match: {
      "arr.v.name": "First"
    }
  },
  {
    $project: {
      arr: 0
    }
  }
])

Mongo Playground

Another hacky approach you can take is potentially creating a wildcard text index and then you could execute a $text query to search for the name, obviously this comes with the text index/query limitations and might not be right for your usecase.

Sign up to request clarification or add additional context in comments.

1 Comment

The schema has been designed to directly retrieve objects within content without the need to search by value whether it exists or not. These keys are defined in the model, they are at most 4 and are optional, that's why this structure, because it is faster and easier to manipulate... until now...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.