更新来自另一个集合的匹配记录
update matched records from another collection?
有人能帮我更新基于另一个集合吗?我有一个像这样的皮卡收集。
{
"_id": {
"$oid": "53a46be700b94521574b6f75"
},
"created": {
"$date": 1403236800000
},
"receivers": [
{
"model": "somemodel1",
"serial": "someserial1",
"access": "someaccess1"
},
{
"model": "somemodel2",
"serial": "someserial2",
"access": "someaccess2"
},
{
"model": "somemodel3",
"serial": "someserial3",
"access": "someaccess3"
}
],
"__v": 0
}
我想遍历接收器数组并在另一个集合中搜索每个访问,如果找到,添加它在其中找到的活动。
这是我要搜索的工作订单集合。
{
"_id": {
"$oid": "53af72481b2aeade0b46d025"
},
"activityNumber": "someactivity",
"date": "06/28/2014",
"lines": [
{
"Line #": "1",
"Access Card #": "someaccess1"
},
{
"Line #": "2",
"Access Card #": "someaccess2"
},
{
"Line #": "3",
"Access Card #": "someacess3"
}
],
}
这就是我想要结束的。
{
"_id": {
"$oid": "53a46be700b94521574b6f75"
},
"created": {
"$date": 1403236800000
},
"receivers": [
{
"model": "somemodel1",
"serial": "someserial1",
"access": "someaccess1",
"activityNumber": "someactivity"
},
{
"model": "somemodel2",
"serial": "someserial2",
"access": "someaccess2",
"activityNumber": "someactivity"
},
{
"model": "somemodel3",
"serial": "someserial3",
"access": "someaccess3",
"activityNumber": "someactivity"
}
],
"__v": 0
}
我已经创建了一个数组,其中包含了所有来自拾取的访问。
var prodValues = db.pickups.aggregate([
{ "$unwind":"$receivers" },
{ "$group": {
"_id": null,
"products": { "$addToSet": "$receivers.access"}
}}
])
我可以很容易地遍历数组并搜索工作订单集合,并返回使用它们的活动。但是我不确定如何执行查找并在找到时更新拾取集合。
db.workorders.find({ "lines.Access Card #": { "$in": prodValues.result[0].products }},{activityNumber:1})
谢谢你的帮助。
我应该按照完全相反的顺序来循环,因为这样会更有效率:
var result = db.workorders.aggregate([
{ "$project": {
"activityNumber": 1,
"access": "$lines.Access Card #",
}}
]).result;
result.forEach(function(res) {
res.access.forEach(function(acc) {
db.pickups.update(
{ "receivers.access": acc },
{ "$set": { "receivers.$.activityNumber": res.activityNumber } }
);
});
});
在mongodb 2.6中,您可以通过在聚合输出上添加游标和使用批量操作API来解决这个问题:
var batch = db.pickups.initializeOrderedBulkOp();
var counter = 0;
db.workorders.aggregate([
{ "$project": {
"activityNumber": 1,
"access": "$lines.Access Card #",
}}
]).forEach(function(res) {
res.access.forEach(function(acc) {
batch.find({ "receivers.access": acc }).updateOne(
{ "$set": { "receivers.$.activityNumber": res.activityNumber } }
);
});
if ( counter % 500 == 0 ) {
batch.execute();
var batch = db.pickups.initializeOrderedBulkOp();
counter = 0;
}
});
if ( counter > 0 )
batch.execute();
无论哪种方式,基本上都是将文档和数组的位置与第一个聚合查询返回的"access"值和当前行中的值进行匹配。这允许在指定位置更新相关信息。
MongoDB 2.6的改进是,您不会将所有结果从"workoders"集合中作为数组拉到内存中,因此只有每个文档从游标结果中拉入。
Bulk操作操作将"更新"存储在可管理的块中,这些块应该低于16MB BSON限制,然后您将这些块发送,而不是单独的更新。驱动程序实现应该处理大部分这些,但是为了安全起见,添加了一些"自我管理"。
相关文章:
- 使用Dnamics CRM 2011中的JavaScript读取子网格的所有记录,而不考虑活动页面
- 如何使jQuery插件函数可调用以供独立使用,而不在集合上操作
- Meteor-将选定窗体中的对象添加到集合中
- 主干集合重置和解析
- 在 Meteor 中,如何在给定年份、月份、日期的集合中找到记录
- 主干(也是木偶)尝试在集合开始时显示新记录,而不重新渲染整个集合
- Sails.io.js:订阅记录的子集合
- API返回3条记录-主干集合不匹配
- 在流星中呈现之前,如何解析对其他集合中db记录的引用
- 循环遍历Firebase数据库记录的集合
- 更新来自另一个集合的匹配记录
- Meteor JS:我如何访问集合中的前一个记录
- 当记录添加到集合中时,将默认数组对象添加到子数组中
- 如何迭代地创建记录集合并一次呈现所有记录
- 无法在node.js中使用mongo访问mongo集合的记录
- DerbyJS从集合中查找记录
- 在Backbone.js集合中记录更改,我的集合未定义
- 获取与模型相关的所有集合记录
- 如何正确地将额外的对象字段持久化到mongodb集合中的所有记录
- 如何将新记录插入到现有集合:Sails.js