我有一个文档集合,其中的一个内部属性是一个对象数组,但是这些对象被错误地存储在内部数组中,例如以下实例,特别是“ recs”属性:
{
"_id": ObjectId("5d52e851b412ca0001f10038"),
"idIntegracaoContabil": NumberLong(6583),
"protocol": "489dsad3-b075-4bc2-8631-9c01cc778e75",
"content": {
"idInteg": "1f2bd0d3b48978c286319c01cc778e75",
"recs": [
[
{
"desc": "Lorem ipsum dolor sit amet",
"type": "TYPE1"
},
{
"desc": "Sed ut perspiciatis unde omnis iste natus error",
"type": "TYPE2"
}
],
[
{
"desc": "Et harum quidem rerum facilis est et expedita distinctio",
"type": "TYPE3"
}
]
]
},
"createdBy": "admin"
}
现在,我需要更新此集合的所有元素,将这些数组展平为desc / type对象的单个数组。我已经查询过应该使用$ unwind之类的聚合函数来获得此结果,但是我不知道如何在更新中做到这一点。
答案 0 :(得分:0)
如果您的MongoDB版本> = 3.4,我相信最好的方法是使用运算符$reduce来使数组变平。
您可以这样做:
db.your_collection.aggregate(
[
{
$project: {
"_id": 1,
"idIntegracaoContabil": 1,
"protocol": 1,
"content.idInteg": 1,
"content.recs": {
$reduce: {
input: '$content.recs',
initialValue: [],
in: {$concatArrays: ['$$value', '$$this']}
}
},
"createdBy": 1,
}
},
{$out: "your_collection"}
]
)
如您所见,在这种情况下,您需要将所有字段添加到投影中,以便使用$out
保存文档的更新版本。如果您不在乎是否使用聚合,则可以在find()
游标上进行迭代:
db.your_collection.find({}).forEach(
function(doc) {
doc.content.recs = doc.content.recs.reduce((a, b) => a.concat(b), []);
db.your_collection.save(doc);
}
)
尽管这种方法的性能不如聚合,但有时会派上用场。例如,我更喜欢在使用Mongo Shell时使用这种方法,因为它的语法更容易记住,并且只允许我们处理需要更改的字段。在我的汇总示例中,如果您忘记在投影中添加一个字段,则文档将被保存而没有该字段。