简体   繁体   中英

mongodb - adding the value in a field to the value in an embedded array

I have a document in MongoDB as below.

{                                                              
  "CorePrice" : 1,
  "_id" : 166,
  "partno" : 76,
  "parttype" : "qpnm",
  "shipping" :
    [
      {
        "shippingMethod1" : "ground",
        "cost1" : "10"
      },
      {
        "shippingMethod2" : "air",
        "cost2" : "11"
      },
      {                                                              
        "shippingMethod3" : "USPS",
        "cost3" : "3"
      },
      {
        "shippingMethod4" : "USPS",
        "cost4" : 45
      }
    ]
}

My goal is to add CorePrice (1) to cost4 (45) and retrieve the computed value as a new column "dpv". I tried using the below query. However I receive an error exception: $add only supports numeric or date types, not Array . I'm not sure why. Any kind of help will be greatly appreciated.

db.Parts.aggregate([
  {
    $project: {
      partno: 1,
      parttype: 1,
      dpv: {$add: ["$CorePrice","$shipping.cost1"]}
    }
  },
  {
    $match: {"_id":{$lt:5}}
  }
]);

When you refer to the field shipping.cost1 and shipping is an array, MongoDB does not know which entry of the shipping -array you are referring to. In your case there is only one entry in the array with a field cost1 , but this can't be guaranteed. That's why you get an error.

When you are able to change your database schema, I would recommend you to turn shipping into an object with a field for each shipping-type. This would allow you to address these better. When this is impossible or would break some other use-case, you could try to access the array entry by numeric index ( shipping.0.cost1 ).

Another thing you could try is to use the$sum -operator to create the sum of all shipping.cost1 fields. When there is only one element in the array with a field cost1 , the result will be its value.

I am able to achieve this by divorcing the query into two as below.

var pipeline1 = [
    {
        "$unwind": "$shipping"
    }, 
    {
        $project:{
            partno:1, 
            parttype:1,
            dpv:{
                $add:["$CorePrice","$shipping.cost4"]
            }
        }
    }, 
    {
        $match:{"_id":5}
    }
];               

R = db.tb.aggregate( pipeline );

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