0

Is it possible to find the 'field name' using a regex first and then use that field name to find its value across all documents?

For example, if I have the following structure:

item : Object
  - quantity: 50
  - size: Object
    - h: 20

Ideally, if I want the value of h, I would query item.quantity.size.h ("field.nestedField"). However, I only know the name 'h' but not what it is nested under. Is it possible to retrieve the entire field name (item.quantity.size.h) and its value (20)? I would then like to use that field name to obtain the value from all other documents.

Sassy
  • 11
  • 2
  • Please provide example data. Is a level an object or an array? – nimrod serok Apr 01 '22 at 06:22
  • @Sassy your newly added sample data is still not clear about its structure. It would be the best if you can provide valid json documents. – ray Apr 02 '22 at 15:13

1 Answers1

0

Inspired by: MongoDB javascript `"$function"` not returning expected value in mongoplayground.net

You can use a $function aggregation, like this:

    db.collection.aggregate([
  {
    $project: {
      data: "$$ROOT"
    }
  },
  {
    "$project": {
      "flattenKeys": {
        "$function": {
          "body": "function flatten(dataList, keysToHandle){while(keysToHandle.length){origKeyData = keysToHandle.shift();for (const newKey of Object.keys(origKeyData.objData)){keysToHandle.push({objData:origKeyData.objData[newKey],keyData:`${origKeyData.keyData}.${newKey}`});dataList.push(`${origKeyData.keyData}.${newKey}`);}}return dataList}",
          "args": [
            [],
            [
              {
                objData: "$data",
                keyData: "data"
              }
            ]
          ],
          "lang": "js"
        }
      }
    }
  },
  {
    $project: {
      matchingKeys: {
        $filter: {
          input: "$flattenKeys",
          as: "item",
          cond: {
            $regexMatch: {
              input: "$$item",
              regex: "keyD"
            }
          }
        }
      }
    }
  }
])

See how it works here

nimrod serok
  • 14,151
  • 2
  • 11
  • 33