简体   繁体   中英

node api to fetch subdocuments using mongoose

My MongoDB stores documents having the following structure:

{
    "application_detail":{},
    "curl_detail":{
        "Curl1":{
            "key1":"value1",
            "key2":"value2"
        },
        "Curl2":{
            "key1":"value1",
            "key2":"value2"        
        },
        "Curl3":{
            "key1":"value1",
            "key2":"value2"
        },
        "Curl4":{
            "key1":"value1",
            "key2":"value2"
        },
        /*total number of curls are unknown*/
    }
}

How can I fetch key1 for all the curls present under curl_detail from mongoDB using express and mongoose?

Expected Output:

{
    "curl_detail": {
        "Curl1": {
            "key1": "value1"
        },
        "Curl2": {
            "key1": "value1"
        },
        "Curl3": {
            "key1": "value1"
        },
        "Curl4": {
            "key1": "value1"
        }
    }
}

NOTE: Total number of curls are unknown.

I would like to propose you changing data structrure from

"curl_detail": {
    "Curl1": {
        "key1": "value1",
        "key2": "value2"
    },
    "Curl2": {
        "key1": "value1",
        "key2": "value2"
    }
}

to

"curl_detail": [{
        "key1": "value1",
        "key2": "value2"
    },
    {
        "key1": "value1",
        "key2": "value2"
    }
]

Storing data structure in array will allow you to find some data in an easier way. Also there's no need to have object with properties like Curl1 , Curl2 etc.

For the new data structure there are already some answers with the explanation:

1) Mongo find value with unknown parent key

2) Query MongoDB by value when parent key is unknown

3) MongoDB: Find document given field values in an object with an unknown key

UPDATE

If there's no possibility to change the data structure please see this solution (trick with use of $arrayToObject / $objectToArray to determine the name of nested key eg "Curl1"):

db.collection.aggregate([{
        $addFields: {
            curl_detail: {
                $arrayToObject: {
                    $map: {
                        input: {
                            $objectToArray: "$curl_detail"
                        },
                        as: "details",
                        in: {
                            k: "$$details.k",
                            v: {
                                key1: "$$details.v.key1"
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $project: {
            _id: 0,
            curl_detail: 1
        }
    }
])

This outputs the following:

[
  {
    "curl_detail": {
      "Curl1": {
        "key1": "value1"
      },
      "Curl2": {
        "key1": "value1"
      },
      "Curl3": {
        "key1": "value1"
      },
      "Curl4": {
        "key1": "value1"
      }
    }
  }
]

You can check it through Mongo Playground

You can use projection for the query you are looking for:

collection.find({}, {"curl_detail":1}, (findError, results) => {
  if(findError) { 
    //handle the error
    return;
  }
  // here is the expected result
  console.log();
});

If this result also works for you:

[
  {
    "curl_detail": {
      "Curl1": "value1",
      "Curl2": "value1",
      "Curl3": "value1",
      "Curl4": "value1"
    }
  }
]

You can use the following aggregation using the $objectToArray and $arrayToObject

db.collection.aggregate([
  {
    $addFields: {
      curl_detail: {
        $map: {
          "input": {
            "$objectToArray": "$curl_detail"
          },
          "as": "el",
          "in": {
            "k": "$$el.k",
            "v": "$$el.v.key1",

          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      curl_detail: {
        $arrayToObject: "$curl_detail"
      }
    }
  }
])

Playground

You can use this aggregation with mongoose like this, let's say your model is MyModel:

MyModel.aggregate([
  {
    $addFields: {
      curl_detail: {
        $map: {
          input: {
            $objectToArray: '$curl_detail'
          },
          as: 'el',
          in: {
            k: '$$el.k',
            v: '$$el.v.key1'
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      curl_detail: {
        $arrayToObject: '$curl_detail'
      }
    }
  }
]).then(res => {
  console.log(res);
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM