Home > Enterprise >  How to query mongodb wildcard sub fields in filter and projection?
How to query mongodb wildcard sub fields in filter and projection?

Time:10-27

I have this structure of a document:

{
  "1": {
    "type1": 1,
    "type2": 2
  },
  "2": {
    "type1": 11,
    "type2": 12
  }
}
// There can by multiple values at all levels, not just 2

Now I want to to query for all type2 with a filter, conceptually:

"*.type2" > 10

And I want to return only one field as well, so that the result would look like that:

{
  "10": {
    "type2": 20
  },
  "20": {
    "type2": 25
  }
}

Is it possible to achieve in MongoDB with a single query?

CodePudding user response:

One option is to iterate over the keys and keep only the type2 with value greater than 10. In order to iterate over the keys we are using $objectToArray. In order to keep only the type2, we use $reduce to iterate (which allow to format the item), instead of a simple $filter that will just return the un-formatted matching items. The last step is just to format back the array to a dictionary.

db.collection.aggregate([
  {$project: {
      _id: 0,
      data: {$reduce: {
          input: {$objectToArray: "$$ROOT"},
          initialValue: [],
          in: {$concatArrays: [
              "$$value",
              {$cond: [
                  {$gt: ["$$this.v.type2", 10]},
                  [{k: "$$this.k", v: {type2: "$$this.v.type2"}}],
                  []
              ]}
          ]}
      }}
  }},
  {$replaceRoot: {newRoot: {$arrayToObject: "$data"}}}
])

See how it works on the playground example

  • Related