如果您有办法选择整个文档,可以。 update 方法将接受一个聚合管道作为将应用于匹配文档的第二个参数。
有几种方法可以实现这一点。一种可能性是:
- 使用$reduce 将网站数组拆分为匹配数组和剩余数组,
- 如果没有匹配,则创建一个存根元素,或者从匹配数组中提取第一个元素
- 将新测试附加到测试数组
- 将站点元素附加到剩余的数组
- 删除临时字段
address="NewString";
testElement={result:"NewString",type:"NewString"};
Collection.update({},[
{$set:{
match_result:{
$reduce:{
input:"$websites",
initialValue:{matched:[],remain:[]},
in: {
matched:{$cond:[{$eq:["$$this.site_address",address]},{$concatArrays:["$$value.matched",["$$this"]]},"$$value.matched"]},
remain:{$cond:[{$ne:["$$this.site_address",address]},{$concatArrays:["$$value.remain",["$$this"]]},"$$value.remain"]},
}
}
}
}},
{$set:{
new_site:{$cond:[{$eq:[{$size:"$match_result.matched"},0]},{site_address:"NewString",tests:[]},{$arrayElemAt:["$match_result.matched",0]}]}
}},
{$set: { "new_site.tests":{$concatArrays:["$new_site.tests",[testElement]]}}},
{$set:{ websites:{$concatArrays:["$match_result.remain",["$new_site"]]}}},
{$project: {
match_result:0,
new_site:0
}}
])
这可能最终会比单独查询然后更新更差,因此应该按顺序进行一些测试。