mongodb - 如何将子文档复制到同一个文档中
问题描述
我需要从文档中复制一个子文档并插入到同一个文档中。但是我使用 forEach 和 findAndModify 它不能插入到同一个文档中。
文档示例:
{
"_id" : ObjectId("59b5e84d71ab5580d643d070"),
"modifiedOn" : ISODate("2019-04-03T14:57:22.177+0000"),
"modifiedBy" : "XXX",
"createdOn" : ISODate("2017-09-09T16:33:34.464+0000"),
"createdBy" : "liuyu",
"channelSales" : [
{
"platform" : "amazon",
"channel" : "amazon_ca",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39dc1")
},
{
"platform" : "amazon",
"channel" : "amazon_uk",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39dc0")
},
{
"platform" : "amazon",
"channel" : "amazon_us",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39dbf")
},
{
"platform" : "amazon",
"channel" : "amazon_jp",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39dbe")
},
{
"platform" : "amazon",
"channel" : "amazon_de",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39dbd")
},
{
"platform" : "amazon",
"channel" : "amazon_es",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39dbc")
},
{
"platform" : "amazon",
"channel" : "amazon_fr",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39dbb")
},
{
"platform" : "amazon",
"channel" : "amazon_it",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39dba")
},
{
"platform" : "ebay",
"channel" : "ebay_au",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39db9")
},
{
"platform" : "ebay",
"channel" : "ebay_de",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39db8")
},
{
"platform" : "ebay",
"channel" : "ebay_es",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39db7")
},
{
"platform" : "ebay",
"channel" : "ebay_fr",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39db6")
},
{
"platform" : "ebay",
"channel" : "ebay_it",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39db5")
},
{
"platform" : "ebay",
"channel" : "ebay_uk",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39db4")
},
{
"platform" : "ebay",
"channel" : "ebay_us",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("59b5f86aaa0ee15555a39db3")
},
{
"platform" : "walmart",
"channel" : "walmart_us",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("5a4d9de2bb1aee844f03e1a6")
},
{
"platform" : "walmart",
"channel" : "walmart_ca",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("5a4d9de2bb1aee844f03e1a5")
},
{
"platform" : "amazon",
"channel" : "amazon_au",
"saleStatus" : "T",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("5abe095bb1d48d194f6187c0")
},
{
"platform" : "amazon",
"channel" : "amazon_in",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("5c9af2776f3dcf04491818f2")
}
],
"statusLevel" : "",
"statusType" : "",
"status" : "A",
"skuId" : "abc001",
"__v" : NumberInt(3)
}
我想复制:
{
"platform" : "walmart",
"channel" : "walmart_us",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("5a4d9de2bb1aee844f03e1a6")
}
并更改“频道”:“walmart_dsv”,其他文件与此相同:
{
"platform" : "walmart",
"channel" : "walmart_dsv",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"_id" : ObjectId("5a4d9de2bb1aee844f03e1a6")
}
并插入到同一个文档中。
我使用这个命令:
db.getCollection("0521").aggregate([
{$unwind: "$channelSales"},
{$project: {platform: "$channelSales.platform",
channel: "$channelSales.channel",
saleStatus: "$channelSales.saleStatus",
type: "$channelSales.type",
url: "$channelSales.url",
remark: "$channelSales.remark",
isCaught: "$channelSales.isCaught",
_id: "$channelSales._id"
}},
{ $match : { "channel" : "amazon_us"} }
]).forEach(function(award_team){
if(award_team != null)
{
db.getCollection("0521").findAndModify(
{
query: {_id: award_team._id},
update: { $push: {channelSales: [ {platform: award_team.platform, channel: "walmart_dsv", saleStatus: award_team.saleStatus, type: award_team.type, url: award_team.url, remark: award_team.remark, isCaught: award_team.isCaught, _id: award_team._id }] } },
upsert: true,
});
}
});
但它是添加一个新文件,我该怎么办?
解决方案
您在投影中犯了一个错误:您正在使用子文档 _id 来更新主文档,并且您正在使用选项{upsert: true}
,因此每次插入新文档以防找不到 _id。如下更新您的项目:
db.collection.aggregate([
{$unwind: "$channelSales"},
{$project: {
_id: "$_id", // Main Document Id
platform: "$channelSales.platform",
channel: "$channelSales.channel",
saleStatus: "$channelSales.saleStatus",
type: "$channelSales.type",
url: "$channelSales.url",
remark: "$channelSales.remark",
isCaught: "$channelSales.isCaught",
channelSalesId: "$channelSales._id" // Sub-Document Id (Caannel Sales Id)
}},
{ $match : { "channel" : "amazon_us"} }
])
现在您将收到如下响应:
{
"_id" : ObjectId("59b5e84d71ab5580d643d070"),
"platform" : "amazon",
"channel" : "amazon_us",
"saleStatus" : "A",
"type" : "",
"url" : "",
"remark" : "",
"isCaught" : "0",
"channelSalesId" : ObjectId("59b5f86aaa0ee15555a39dbf")
}
现在您可以使用“award_team._id”来更新文档:
db.getCollection("0521").findAndModify(
{
query: {_id: award_team._id},
update: { $push: {channelSales: [ {platform: award_team.platform, channel: "walmart_dsv", saleStatus: award_team.saleStatus, type: award_team.type, url: award_team.url, remark: award_team.remark, isCaught: award_team.isCaught, _id: award_team._id }] } },
upsert: true,
});
}
});
推荐阅读
- c++ - 为什么指向基类的派生类指针可以调用派生类成员函数?
- arrays - 如何在C函数中将未知大小的矩阵作为参数传递?
- node.js - Node-Postgres/Knex 在 JS 中返回 CITEXT[] 作为字符串,而不是字符串数组
- swift - 导航到视图时刷新视图
- wordpress - 如何通过在新页面的 URL 中添加参数从联系表 7 中获取值并将其预填充到另一个页面中?
- javascript - 通过输入特定文本添加元素的输入
- django - 具有继承 django 模型的可写嵌套序列化器
- numpy - numpy 计算序列如何影响结果?
- javascript - 使 p-dropdown 可编辑使其显示 [object Object]
- sql - oracle sql存储过程,创建数字(10)的临时本地缓存