2014-02-24 19 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应该为我正确插入一个新文档。 –

相关问题