因此,您应该从您引用的问题中意识到,在没有实际查找文档并循环结果以生成更新的情况下,当更新另一个字段时,您实际上无法引用文档中的另一个值。
因此,底线是您将真正在代码中执行此操作,读取每个文档并从中提取新值以形成新数组。可以使用$set 创建新数组,或者在更新中使用$push 和$each 运算符可能更安全。
理想情况下,您也可以使用Bulk Operations API 来获得最佳更新形式。
最后你也可以将一些数组构造工作委托给aggregation framework,而不是在客户端代码中全部处理,但是更新仍然需要对结果进行:
var bulk = db.collection.initializeOrderedBulkOp();
var count = 0;
var cursor = db.collection.aggregate([
{ "$project": {
"array2": {
"$map": {
"input": "array1",
"as": "el",
"in": "$$el.fld1"
}
}
}}
]);
cursor.forEach(function(doc) {
bulk.find({ "_id": doc._id }).updateOne({
"$push": { "array2": { "$each": doc.array2 } }
});
count++;
// send and drain once every 1000 documents
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.collection.initializeOrderedBulkOp();
}
});
// If the counter is uneven then send
if ( count % 1000 != 0 )
bulk.execute();
原来如此。您可以将聚合框架与 $map 这样的运算符一起使用,以便从数组中提取所需的元素,或者考虑到您并没有真正“聚合”任何东西,您可以使用类似的方法在代码中执行此操作。这里的主要情况是,无论您使用哪种语言,您都需要在代码中循环结果。
当然,如果您可以只使用更改后的结果创建一个“新”集合,那么聚合的 $out 管道阶段可能非常适合您:
db.collection.aggregate([
{ "$project": {
"array1": 1,
"array2": {
"$map": {
"input": "array1",
"as": "el",
"in": "$$el.fld1"
}
}
}},
{ "$out": "newcollection" }
]);
简而言之,尽管您需要部分或全部这些技术来获得您正在寻找的更改后的收集结果。所以要么直接使用它,要么实现其中的一些。