mongodb - 将字段中的值添加到嵌入数组中的值

时间:2013-09-30 01:36:27

标签: arrays mongodb

我在MONGODB中有一份文件如下。

{                                                              
"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                                 
    }]
} 

Q))我的目标是将CorePrice(1)添加到cost4(45)并将计算值检索为新列“dpv”。我尝试使用以下查询。但是我收到错误“异常:$ add仅支持数字或日期类型,而不是数组”。不知道为什么。任何形式的帮助将不胜感激。

db.Parts.aggregate({$project:{partno:1, parttype:1, 

dpv:{$add:["$CorePrice","$shipping.cost1"]}}}, {$match:

{"_id":{$lt:5}}}); 

2 个答案:

答案 0 :(得分:1)

当您引用字段shipping.cost1shipping是一个数组时,MongoDB不知道您引用的shipping - 数组的哪个条目。在您的情况下,数组中只有一个带有字段cost1的条目,但这不能保证。这就是你收到错误的原因。

当您能够更改数据库架构时,我建议您将shipping转换为具有每个送货类型字段的对象。这样可以让您更好地解决这些问题。如果这不可能或者会破坏其他一些用例,您可以尝试通过数字索引(shipping.0.cost1)访问数组条目。

您可以尝试的另一件事是使用$sum-operator创建所有shipping.cost1字段的总和。如果数组中只有一个元素带有字段cost1,则结果将是其值。

答案 1 :(得分:0)

我能够通过将查询分成两部分来实现这一点。

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

R = db.tb.aggregate( pipeline );