2015-11-16 38 views
1

考慮一個集合與下列文件更新文件

{ 
     "_id" : "aaaaaaaaaaaa", 
     "title" : "Hello, World!", 
     "date" : "Thursday, November 12, 2015", 
     "time" : "9:30 AM", 
     "endtime" : "11:30 AM" 
}, 
{ 
     "_id" : "bbbbbbbbbbbb", 
     "title" : "To B or not to B", 
     "date" : "Thursday, November 12, 2015", 
     "time" : "10:30 AM", 
     "endtime" : "11:00 AM" 
}, 
{ 
     "_id" : "cccccccccccc", 
     "title" : "Family Time", 
     "date" : "Thursday, November 12, 2015", 
     "time" : "10:30 AM", 
     "endtime" : "12:00 PM" 
} 

在這個簡化的輸出,我有他們的開始時間,結束時間和日期都進入了爲字符串事件。如何使用update()中使用現有數據的字段來計算我可以實際查詢的新的正確形成的Date()類型數據。

以下工作來創建一個新的「iso_start」字段

db.events.update({},{$set: {iso_start:Date()}},{multi: true})

我想象我將能夠建立一種更新,選擇像這樣

db.events.update({},{$set: {iso_start:Date(date + " " + time)}},{multi: true})db.events.update({},{$set: {iso_end:Date(date + " " + time)}},{multi: true})

但我收到錯誤「日期未定義」。

更新:this.datethis.time使未定義的錯誤消失,但插入的日期是針對當前日期時間。我試着寫new Date()但隨後插入日期是ISODate(「0NaN-NAN-NaNTNaN:楠:NaNZ」)

+0

對不起,我感到困惑,忽略了你的答案,並以另一種方式解決了我的問題。我試圖確認,在我將其標記爲正確之前,它實際上是正確的答案。 –

回答

1

您需要使用.aggregate()方法,它提供了訪問,以聚集管道。

在你$project階段,你需要使用$concat運算符來連接你的領域。

然後,您可以使用您的聚合結果更新使用"bulk"運營效率

var bulk = db.events.initializeOrderedBulkOp(); 
var count = 0; 
db.events.aggregate([ 
    { "$project": { 
     "iso_start": { "$concat": [ "$date", " ", "$time" ] }, 
     "iso_end": { "$concat": [ "$date", " ", "$endtime" ] }  
    }} 
]).forEach(function(doc) { 
    bulk.find({'_id': doc._id}).updateOne({ 
     "$set": { 
      "iso_start": new Date(doc.iso_start), 
      "iso_end": new Date(doc.iso_end) 
     } 
    }); 
    count++; 
    if(count % 200 === 0) { 
     // update per 200 operations and re-init 
     bulk.execute();  
     bulk = db.events.initializeOrderedBulkOp(); 
    } 
}) 
// Clean up queues 
if(count > 0) bulk.execute(); 

您的收藏此操作後您的文檔看起來是這樣的:

{ 
     "_id" : "aaaaaaaaaaaa", 
     "title" : "Hello, World!", 
     "date" : "Thursday, November 12, 2015", 
     "time" : "9:30 AM", 
     "endtime" : "11:30 AM", 
     "iso_start" : ISODate("2015-11-12T06:30:00Z"), 
     "iso_end" : ISODate("2015-11-12T08:30:00Z") 
} 
{ 
     "_id" : "bbbbbbbbbbbb", 
     "title" : "To B or not to B", 
     "date" : "Thursday, November 12, 2015", 
     "time" : "10:30 AM", 
     "endtime" : "11:00 AM", 
     "iso_start" : ISODate("2015-11-12T07:30:00Z"), 
     "iso_end" : ISODate("2015-11-12T08:00:00Z") 
} 

也就是說不是故事的結尾,因爲"Bulk" API及其關聯的方法已被棄用在即將發佈的版本(版本3.2)中,因此從該版本開始,我們將需要使用db.collection.bulkWrite()方法。

var operations = []; 
db.events.aggregate([ 
    { "$project": { 
     "iso_start": { "$concat": [ "$date", " ", "$time" ] }, 
     "iso_end": { "$concat": [ "$date", " ", "$endtime" ] }  
    }} 
]).forEach(function(doc) { 
    var operation = { 
     updateOne: { 
      filter: { "_id": doc._id }, 
      update: { 
       "$set": { 
        "iso_start": new Date(doc.iso_start), 
        "iso_end": new Date(doc.iso_end) 
       } 
      } 
     } 
    }; 
    operations.push(operation); 
}) 
operations.push({ ordered: true, writeConcern: { w: "majority", wtimeout: 5000 } }); 
db.events.bulkWrite(operations)