使用MongoDB中的聚合管道将计算字段添加到数组字段中的文档中

使用MongoDB中的聚合管道将计算字段添加到数组字段中的文档中,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我试图在数组中添加一个表示文档相对权重的字段。我在这里展示了以下数据模型和两个文档: db.pos.insertMany([ {"asof": "2020-02-05", "holdings": [ {"fid": 1,"shares": 50}, {"fid": 2,"shares": 50} ], "portfo

我试图在数组中添加一个表示文档相对权重的字段。我在这里展示了以下数据模型和两个文档:

db.pos.insertMany([
  {"asof": "2020-02-05",
  "holdings": [
    {"fid": 1,"shares": 50},
    {"fid": 2,"shares": 50}
  ],
  "portfolio_id": 10,
  "user": "xxx"
  },
  {"asof": "2020-02-02",
  "holdings": [
    {"fid": 1,"shares": 40},
    {"fid": 2,"shares": 60},
    {"fid": 3,"shares": 30}
  ],
  "portfolio_id": 10,
  "user": "xxx"
  }]);
现在,对于数组字段“holdings”中的每个文档,我试图添加“wt”,它只是shares/sum(shares),其中sum将接管holdings中的所有文档。 我的目标是返回添加了“wt”的整个文档,因此最终结果如下所示:

{ "_id": ObjectId()
  "asof": "2020-02-05",
  "holdings": [
    {"fid": 1,"shares": 50, "wt": 0.5},
    {"fid": 2,"shares": 50, "wt": 0.5}
  ],
  "portfolio_id": 10,
  "user": "xxx"
  },

  {"_id": ObjectId()
  "asof": "2020-02-02",
  "holdings": [
    {"fid": 1,"shares": 40, "wt": 0.3076923},
    {"fid": 2,"shares": 60, "wt": 0.4615384},
    {"fid": 3,"shares": 30, "wt": 0.2307692}
  ],
  "portfolio_id": 10,
  "user": "xxx"
  }
我尝试过使用$addField或$project以及$map($divide和$sum)的路线/阶段,其中一些路线/阶段比其他路线/阶段更接近预期结果。但是,我远没有得到上面所示的“就地”结果。有人能帮我吗?

试试这个:

db.pos.aggregate([
{
$addFields:{
“控股”:{
$map:{
输入:“$holdings”,
作为:“项目”,
在:{
fid:“$$item.fid”,
共享:“$$item.shares”,
wt:{$divide:[“$$item.shares”,{$sum:“$holdings.shares”}]}
}
}
}
}
}
])
输出:

/*1创建日期:2021年3月24日下午5:00:41*/
{
“_id”:ObjectId(“605b22e149e1013fd8c32337”),
“asof”:“2020-02-05”,
“控股”:[
{
“fid”:1,
“股份”:50,
“wt”:0.5
},
{
“fid”:2,
“股份”:50,
“wt”:0.5
}
],
“投资组合id”:10,
“用户”:“xxx”
},
/*创建日期:2021年3月24日下午5:00:41*/
{
“_id”:ObjectId(“605b22e149e1013fd8c32338”),
“asof”:“2020-02-02”,
“控股”:[
{
“fid”:1,
“股份”:40,
“重量”:0.3076922307
},
{
“fid”:2,
“股份”:60,
“重量”:0.4615384615384615156
},
{
“fid”:3,
“股份”:30,
“重量”:0.23076923076923077978
}
],
“投资组合id”:10,
“用户”:“xxx”
}

完美!我用$mergeObject和新字段“wt”得到了一个类似的解决方案,但是看看你的解决方案,我发现它是不必要的。谢谢你,先生!很高兴您使用的是
$mergeObjects
,我会检查一下。从来没用过那么多。是的,我是通过用拳头和头敲击键盘才做到这一点的:)我想唯一的区别是我正在将fid和shares合并为一个新的“wt”。你的解决方案更干净。对于ref:in:{$mergeObjects:[“$$this”,{wt:{$divide:[“$$this.shares”,{$sum:$holdings.shares”}]}