首页 > 解决方案 > 如何将子文档复制到同一个文档中

问题描述

我需要从文档中复制一个子文档并插入到同一个文档中。但是我使用 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,
   });
   }
   });

但它是添加一个新文件,我该怎么办?

标签: mongodb

解决方案


您在投影中犯了一个错误:您正在使用子文档 _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,
   });
   }
   });

推荐阅读