2014-02-24 18 views
1

我剛剛從SQL數據庫導入了一些數據到MongoDB集合中,並且正在做一些重構。我剛剛從「YYYY-MM-DD」格式轉換爲字符串日期值有:我可以在控制檯中從日期創建新的ObjectId var嗎?

db.Statistic.find({d: {$exists: false}}).forEach(function (x) { 
    var d = ISODate(x.date); 
    db.Statistic.update(x, {$set: {"d": d}}); 
}); 

這一直運作良好。現在我想用一個使用這個日期的_id重建對象,這樣我就不需要單獨的日期字段。我曾嘗試(和許多變化):

db.Statistic.find({d: {$exists: true}}).forEach(function (x) { 
    var oldId = x._id; 
    x._id = new ObjectId(x.d); 
    db.Statistic.save(x); 
    db.Statistic.remove({_id: oldId}); 
}); 

,但我得到Error: invalid object id: length我假設,因爲控制檯的ObjectID構造函數不接受日期以建立一個新的對象ID。在控制檯中有沒有辦法做到這一點?

回答

0

我已經成功地實現我想要的東西。我結束了一個小腳本 - 我已經包括調試是有用的人,將來萬一信息:

db.Statistic.find(...).sort({"date": 1}).limit(1000).forEach(function (x) { 
    print("id=" + x._id); 
    var idDate = new Date(x._id.getTimestamp()); 
    print("id.date=" + idDate); 
    print("date=" + x.date); 
}); 

在:

db.Statistic.find().forEach(function (x) { 
    var oldId = x._id; 
    print("oldId=" + oldId); 
    var oldMachineTime = ("" + oldId).substring(8, 24); 
    print("oldMachineTime=" + oldMachineTime); 
    print("x.d.getTime=" + x.d.getTime()); 
    var timePart = Math.floor(x.d.getTime()/1000); 
    print("timePart=" + timePart); 
    var timePart16 = timePart.toString(16); 
    print("timePart16=" + timePart16); 
    var newHex = timePart16 + oldMachineTime; 
    print("newHex=" + newHex); 
    x._id = ObjectId(newHex); 
    print("x._id=" + x._id); 
    db.Statistic.save(x); 
    db.Statistic.remove({_id: oldId}); 
}); 

我然後與數據的子集,確認總結,我現在已經將我的SQL表中的原始日期集成到這些對象的ObjectId中。我現在可以刪除舊的日期字段,並在需要時從_id.getTimestamp()中讀取它。

1

是的,你在這裏的邏輯有兩個問題。

首先使用ObjectId()函數,您可以指定一個字符串化的版本的實際ObjectId作爲參數或沒有。所以你不能像你試圖做的那樣把它作爲一個日期。

第二個問題是,你只是不能update(這是什麼save特殊快捷方式)文檔的_id領域。把它看作主鍵。改變它是不允許的。

當你認爲你 _id的不同的策略(不同的問題)的,請注意,要做到這樣的變化,你需要「寫出來」的集合。

也就是說,在shell中生成ObjectId對構造函數有這個限制。某些驅動程序實現提供了一種在Id代中使用自己的日期種子的方法。你是仍然受我提到的相同限制。但是這些信息可能是有用的。下面是引用這兩個職位:

Generating Mongo ObjectId (_id) with custom time?

Create MongoDB ObjectID from date in the past using PHP driver

+0

關於第2部分,我意識到這一點 - 這就是爲什麼我不嘗試更改現有保存文檔的_id的原因。我保存一個新文檔(只是重複使用這些字段),然後刪除舊文檔,以便它位於同一個集合中。我同意我可能應該導入到臨時集合中,然後將重構對象保存到最終集合中。 –

+0

@NicholasTolleyCottrell啊。 ** save **函數(回答中的鏈接)顯式地保持原始'_id'完好無損。那是那裏的問題。現在解釋。 –

+0

我不認爲這是問題,因爲它甚至沒有保存。根據你的文檔:'如果文檔包含_id字段,則save()方法執行一個upsert,查詢_id字段上的集合。如果文檔不存在指定的_id值,則save()方法將執行insert操作。由於我設置了一個新的不存在的_id,因此upsert應該爲我正確插入一個新文檔。 –

相關問題