Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 我可以从控制台中的日期创建新的ObjectId变量吗?_Mongodb - Fatal编程技术网

Mongodb 我可以从控制台中的日期创建新的ObjectId变量吗?

Mongodb 我可以从控制台中的日期创建新的ObjectId变量吗?,mongodb,Mongodb,我刚刚将一些数据从SQL数据库导入MongoDB集合,正在进行重构。我刚刚将“yyyy-mm-dd”格式的字符串日期值转换为: db.Statistic.find({d:{$exists:false}}).forEach(函数(x){ var d=等值日期(x.date); update(x,{$set:{“d”:d}); }); 这很有效。现在我想用使用这个日期的_id重建对象,这样就不需要单独的日期字段。我尝试过(和许多变体): db.Statistic.find({d:{$exists:

我刚刚将一些数据从SQL数据库导入MongoDB集合,正在进行重构。我刚刚将“yyyy-mm-dd”格式的字符串日期值转换为:

db.Statistic.find({d:{$exists:false}}).forEach(函数(x){
var d=等值日期(x.date);
update(x,{$set:{“d”:d});
});
这很有效。现在我想用使用这个日期的_id重建对象,这样就不需要单独的日期字段。我尝试过(和许多变体):

db.Statistic.find({d:{$exists:true}}).forEach(函数(x){
var oldId=x.。\u id;
x、 _id=新对象id(x.d);
db.Statistic.save(x);
删除({u id:oldId});
});

但是我得到了
Error:invalid object id:length
我假设是因为控制台的ObjectId构造函数不接受构建新ObjectId的日期。有没有办法在控制台中执行此操作

是的,您的逻辑有两个问题

首先,使用
ObjectId()
函数,可以指定实际ObjectId的字符串化版本作为参数,也可以不指定任何内容。所以你不能像你想做的那样把它作为约会的种子

第二个问题是您不能(这是一个特殊的快捷方式)文档的_id字段。将其视为主键。不允许更改它

当您为自己的新id(不同的问题)考虑不同的策略时,请注意,要进行此类更改,您需要“写出”到新的集合

也就是说,在shell中生成ObjectId对构造函数有这样的限制。一些驱动程序实现提供了在Id生成中使用自己的日期种子的方法。您仍然受到我提到的相同限制。但这些信息可能有用。这里有两篇文章提到了这一点:


我已经设法实现了我想要的。最后,我编写了一个小脚本,其中包含了调试信息,以防将来对某些人有用:

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});
});
然后,我用一部分数据进行了确认:

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);
});

总之,我现在已经将SQL表中的原始日期集成到这些对象的ObjectId中。我现在可以删除旧的日期字段,并在需要时从
\u id.getTimestamp()
读取它。

关于第2部分,我知道这一点-这就是为什么我不尝试更改现有保存文档的_id。我正在保存一个新文档(只是碰巧重用了这些字段),然后删除旧文档,使其位于同一个集合中。我同意我可能应该导入到一个临时集合中,然后将重构对象保存到最终集合中。@NicholasTolleyCottrell啊。保存功能(应答中的链接)明确地保持原始
\u id
的完整性。这就是问题所在。现在解释。我认为这不是问题所在,因为它甚至没有到达保存。根据您的文档:
如果文档包含一个_id字段,那么save()方法将执行一个upsert,在_id字段上查询集合。如果不存在具有指定的_id值的文档,save()方法将执行插入操作。
因为我正在设置一个新的不存在的_id,所以upsert应该正确地为我插入一个新文档。@NicholasTolleyCottrell底线是,您假定使用构造函数中的日期来调用
ObjectId
。答案告诉你为什么,并给你备选方案,以及你在做什么的信息。如果你需要帮助想出一个新的策略,那么也许是一个新问题。不用说,为了避免混淆,请改用
insert
,因为这正是您要做的。