mongodb – Mongo在Meteor应用程序的_id_字段上给出重复键错误

我正在搜索很长一段时间以及关于这个问题的很多主题.到现在为止,我找不到任何解决方案.而且,对我来说并不是很清楚,希望你能提供帮助.这是我的问题:

我设计了一个Meteor应用程序,Mongo DB中有一个带有订单的集合.通过读取csv文件来填充该集合

import_file_orders = function(file) {
var lines = file.split('%\r\n');
var l = lines.length - 1;
for (var i=0; i < l; i++) {
  var line = lines[i];
  var line_parts = line.split('|');
  var ex_key = line_parts[0];
  var ex_name = line_parts[1];
  var clin_info = line_parts[2];
  var order_info = line_parts[3];
  var clinician_last_name = line_parts[4];
  var clinician_first_name = line_parts[5];
  var clinician_code = line_parts[6];
  var clinician_riziv = line_parts[7]
  var pat_id = line_parts[8];
  Meteor.orders.insert({Patient:pat_id, Exam_code:ex_key, Exam_name:ex_name, Clinical_info:clin_info, Order_info:order_info, Clinician:{first:clinician_first_name, last:clinician_last_name, c_code:clinician_code, riziv:clinician_riziv}, Planned:null});
  console.log("%");
};
}

读取CSV文件后,集合中的某些文档会出错:

duplicate key error index: protocolplanner.Orders.$_id_ dup key: { :     "2ZGvRfuD8iMvRiXJd" } insert failed

当我运行Mongo命令db.Orders.getIndexes()时,我看到有两个索引:

{
  "v" : 1,
  "key" : {
           "_id" : 1
   },
   "name" : "_id_",
   "ns" : "protocolplanner.Orders"
 }

似乎有两个索引:一个_id索引(始终存在且无法删除)和一个_ id _索引.似乎_ id _ index导致错误.所以我有三个问题:

第一:为什么有一个_ id _索引?我在Meteor代码中没有定义索引.
第二:为什么该索引存在重复密钥错误?
第三:似乎我无法删除_ id _ index.为什么?我现在你不能删除_id索引,但在我看来这不是一个_id索引.

你可以看到我完全迷失了.请帮忙!

编辑:

如下面评论,更多信息:

我正在阅读的数据量是10151行.在定义的客户端读取文件的函数.通过允许和拒绝规则,只有管理员用户可以将数据输入到mongo中.线条被正确读取.阅读文件后,应用程序中的所有数据都可用.几秒钟后,Mongo会自动创建索引并显示错误.从那时起,在应用程序中不再显示发生错误的行.

我在Mongo shell中尝试了以下内容:
    db.Orders.find({_ ID: “2ZGvRfuD8iMvRiXJd”})

Mongo给了我正确的文件.这证明了_id确实是由数据插入数据库时​​由Meteor创建的.但是这个_id应该是唯一的,所以我对我的错误完全感到困惑.

编辑2:
经过一些试验和错误后,我有一些关于这个问题的新信息.也许这很有趣,所以我们可以找到这个问题的答案.

如上所述,当我在客户端读取数据时,即使我使用ObjecID而不是Meteor ID,我也会出现重复键错误.但是,当我通过mongoinsert命令将数据直接推送到Mongo时,所有数据都被很好地导入,并且不会发生错误.当我插入这么多数据时,似乎服务器和客户端之间存在冲突(可能是异步时序问题).

此时我正在寻找一个解决方案来读取数据服务器端,希望不会发生错误.

最佳答案 这不会解决您的问题,但它应该指向正确的方向,并且可能使您能够找出可用于创建新问题的问题:

First: Why is there an _id_ index?

没有.只有一个索引,它有一个名称和一个密钥描述符.那不是一回事.默认索引的名称是_id_,其键是_id.

Why is there a dup key error for that index?

_id通常是客户端创建的,而不是服务器端.问题是这些键来自何处,因为2ZGvRfuD8iMvRiXJd肯定不是ObjectId.这可能是一个流星键,或者你使用一些自定义主键,但我不知道这些键是如何生成的.也许生成钥匙的任何东西容易发生碰撞?

关于这方面的更多信息会有所帮助,但是我建议填写一个新问题,这样问题就不会变得太大或者会有很多历史.

Third: Also it seems that I can’t remove the _ id _ index. Why is it?

这是第一个答案的引理:您无法删除强制主键索引.

编辑:

Meteor,默认为generates ids in a different way than MongoDb.这是有道理的,因为the convention for ObjectId makes collisions probable if the number of clients is large(即如果客户端不是服务器实例,而是客户端浏览器,其中可能有2-3个数量级以上).

相反,Meteor显然使用了method to consistently generate pseudo-random numbers on client and server.有趣的是,实现使用了PRNG和falls back to a not crypto-strong deterministic random number generator (Alea).换句话说,找出你的id的生成方式可能很棘手,因为它取决于你环境的很多细节.

解决方法:
尝试使用ObjectId作为主键:

Orders= new Meteor.Collection('Orders', {idGeneration: 'MONGO'});
点赞