Home > OS >  MongoDB - Find if a key exists anywhere in a document
MongoDB - Find if a key exists anywhere in a document

Time:04-15

I'm looking for a way to search a Mongo object for a specific key, and return its value and path if found.

The questions I've seen related to this use dot notation and $exists, since they know the structure of the object. In this case, however, the target field can sometimes be nested three levels deep and sometimes just one level, and I do not know the path to it or its parent key.

CodePudding user response:

Check my mongoplayground below, it can be used up to three level of array. If you want more level, just copy some of code and you can make it.

data

[
  {
    _id: 1,
    "key": [
      {
        "key2": [
          {
            "key3": [
              {}
            ]
          }
        ]
      }
    ]
  },
  {
    _id: 2,
    "key4": 2
  }
]

aggregate

db.collection.aggregate([
  {
    $set: { n1: { $objectToArray: "$$ROOT" } }
  },
  {
    $unwind: {
      path: "$n1",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $unwind: {
      path: "$n1.v",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $set: {
      key_array: [ "$n1.k" ],
      n2: {
        $cond: {
          if: { $eq: [ { $type: "$n1.v" }, "object" ] },
          then: { $objectToArray: "$n1.v" },
          else: null
        }
      }
    }
  },
  {
    $unwind: {
      path: "$n2",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $unwind: {
      path: "$n2.v",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $set: {
      key_array: {
        $concatArrays: [ "$key_array", [ "$n2.k" ] ]
      },
      n3: {
        $cond: {
          if: { $eq: [ { $type: "$n2.v" }, "object" ] },
          then: { $objectToArray: "$n2.v" },
          else: null
        }
      }
    }
  },
  {
    $unwind: {
      path: "$n3",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $unwind: {
      path: "$n3.v",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $set: {
      key_array: {
        $concatArrays: [ "$key_array", [ "$n3.k" ] ]
      }
    }
  },
  {
    $group: {
      _id: "$_id",
      key_array: { $addToSet: "$key_array" }
    }
  },
  {
    $set: {
      key_array: {
        $reduce: {
          input: "$key_array",
          initialValue: [],
          in: { $concatArrays: [ "$$value", "$$this" ] }
        }
      }
    }
  },
  {
    $unwind: "$key_array"
  },
  {
    $match: { key_array: { $ne: null } }
  },
  {
    $group: {
      _id: "$_id",
      key_array: { $addToSet: "$key_array" }
    }
  }
])

result

[
  {
    "_id": 1,
    "key_array": [
      "key",
      "key3",
      "_id",
      "key2"
    ]
  },
  {
    "_id": 2,
    "key_array": [
      "_id",
      "key4"
    ]
  }
]

mongoplayground

  • Related