簡體   English   中英

將現有字段添加到嵌套架構

[英]Add existing fields to nested schema

我的數據庫中有帶有架構的文檔:

var MySchema = new Schema({
  Street: { type: String },
  Age: { type: Number, default: null },
  Date: { type: Date },
  Stuff: [
       {
        _id:false, 
        ThisDate: { type: Date },
        ThisStreet: { type: String }
       }]
});

現在是( Stuff是空的):

db.person.findOne()  
    {
      Street: 'TheStreet',
      Age: 23,
      Date: ISODate("2016-02-19T00:00:00.000Z"),
      Stuff: []
    }

然后我想更新所有文件。 我想要做的是將StreetDate字段移動到Stuff數組並從架構中刪除StreetDate字段。

像這樣:

db.person.findOne()  
    {
      Age: 23,
      Stuff : [ 
      {
        ThisDate : ISODate("2016-02-19T00:00:00.000Z"),
        ThisStreet : "TheStreet"
      }
      ]
    }

我怎么能做到這一點? 此致

由於這是一個“一次性”操作,我會在 shell 中進行,而不是使用任何其他框架。

對於 MongoDB 3.2.x 版本和更多用途, bulkWrite()

var ops = [];

db.person.find({ 
    "Street": { "$exists": true },
    "Date": { "$exists": true }
}).forEach(function(doc) {
    ops.push({
        "updateOne": {
            "filter": { "_id": doc._id },
            "update": {
                "$unset": {
                    "Street": "",
                    "Date": ""
                },
                "$set": {
                    "Stuff": [{
                        "ThisDate": doc.Date,
                        "ThisStreet": doc.Street
                    }]
                }
            }
        }
    });

    if ( ops.length == 1000 ) {
        db.person.bulkWrite(ops);
        ops = [];
    }
})

if ( ops.length > 0 )
    db.person.bulkWrite(ops);

或者對於 MongoDB 2.6.x 和 3.0.x 版本,使用此版本的批量操作:

var bulk = db.person.initializeUnorderedBulkOp(),
    count = 0;

db.person.find({ 
    "Street": { "$exists": true },
    "Date": { "$exists": true }
}).forEach(function(doc) {
    bulk.find({ "_id": doc._id }).updateOne({
        "$unset": {
            "Street": "",
            "Date": ""
        },
        "$set": {
            "Stuff": [{
                "ThisDate": doc.Date,
                "ThisStreet": doc.Street
            }]
        }
    });

    if ( count % 1000 == 0 ) {
        bulk.execute();
        bulk = db.person.initializeUnorderedBulkOp();
    }
});

if ( count % 1000 != 0 )
    bulk.execute();

最重要的是,您需要迭代集合中的文檔,並用重新排列的內容“一一”將它們寫回。 至少在這兩種情況下使用的批量操作 API 會將寫入和響應服務器的負載減少到每 1000 個要處理的集合中的一個文檔。

此外,您不是重寫整個文檔,而是使用$unset刪除所需的字段,並使用$set編寫“僅”您想要的數據


工作示例

db.person.insert(
    {
      "Street": 'TheStreet',
      "Age": 23,
      "Date": ISODate("2016-02-19T00:00:00.000Z"),
      "Stuff": []
    }
)

然后在運行上面的任一 pdate 結果是:

{
        "_id" : ObjectId("56e607c1ca8e7e3519b4ce93"),
        "Age" : 23,
        "Stuff" : [
                {
                        "ThisDate" : ISODate("2016-02-19T00:00:00Z"),
                        "ThisStreet" : "TheStreet"
                }
        ]
}

我建議您使用聚合框架轉換文檔並按照下面的代碼片段中的描述進行更新

db.person.aggregate([
{$project:{Age:1, Stuff:[{Date:"$Date", Street:"$Street"}]}}
]).forEach(function(o){
  var id = o._id;
  delete o._id;
  db.person.update({_id:id, Street:{$exists: true}},o);
});

成功執行后,您的文檔或文檔應如下所示

{ 
    "_id" : ObjectId("56e2cd45792861e14df1f0a9"), 
    "Age" : 23.0, 
    "Stuff" : [
        {
            "Date" : ISODate("2016-02-19T00:00:00.000+0000"), 
            "Street" : "TheStreet"
        }
    ]
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM