E11000重复键错误索引:MongoDb异常错误
我有一个简单的“用户”集合,其中现在只有2个文档E11000重复键错误索引:MongoDb异常错误,mongodb,erlang,Mongodb,Erlang,我有一个简单的“用户”集合,其中现在只有2个文档 { "_id": ObjectId("4ef8e1e41d41c87069000074"), "email_id": { "0": 109, "1": 101, "2": 64, "3": 97, { "_id": ObjectId("4ef6d2641d41c83bdd000001"), "email_id": { "0": 109
{
"_id": ObjectId("4ef8e1e41d41c87069000074"),
"email_id": {
"0": 109,
"1": 101,
"2": 64,
"3": 97,
{
"_id": ObjectId("4ef6d2641d41c83bdd000001"),
"email_id": {
"0": 109,
"1": 97,
"2": 105,
"3": 108,
现在,如果我试图在email_id字段上创建一个带有{unique:true}的新索引,mongodb会向我抱怨“E11000重复键错误索引:db.users.$email_id dup key:{:46}”。即使在指定了{dropDups:true}之后,我也会遇到相同的错误,但是我认为这里不是这样,因为两个文档都存储了不同的电子邮件id
我不确定这里发生了什么,任何指点都将不胜感激
编辑:文档的完整视图:
{
"_id": ObjectId("4ef8e1e41d41c87069000074"),
"email_id": {
"0": 109,
"1": 101,
"2": 64,
"3": 97,
"4": 98,
"5": 104,
"6": 105,
"7": 110,
"8": 97,
"9": 118,
"10": 115,
"11": 105,
"12": 110,
"13": 103,
"14": 104,
"15": 46,
"16": 99,
"17": 111,
"18": 109
}
}
及
还有几个字段,如“display\u name”、“registed\u since”等,我在上面的显示中省略了这些字段(我认为它们在抛出的错误中没有任何作用,如果您仍然需要它们,我可能可以将整个文档粘贴到这里)
我正在使用与我的mongo实例通信。可以看到的所有字段都保存为二进制字节,这就是为什么您会在文档中看到如此奇怪的电子邮件id
注意:二进制字节格式不是由我的代码逻辑强制的,我经常在我的bson文档中传递字符串email_id,但我总是将我的数据视为二进制字节。(可能是因为erlang mongodb驱动程序是如何编写的,我并没有对此进行真正的研究,因为我的find()、find_one()和其他查询即使使用保存为二进制字节的字段也能按预期工作)
编辑:>db.users.findOne()
当MongoDB索引数组字段时,它实际上索引数组中的单个元素。这是为了有效地支持查找数组特定元素的查询,如:
db.users.find({email_id: 46})
由于这两个文档中都存在此电子邮件\u id
(46),因此您的唯一索引中存在重复键
如果设置了
dropDups:true
set,我不确定为什么会出现此错误。。。您能否显示一个代码示例,说明如何调用createIndex
?您还应该尝试dropDups:1
,因为MongoDB在此上下文中错误地对待1
和true
(请参阅)。对于其他有此问题的人,请使用db.version()
检查您的mongo版本。如果您正在运行Mongo 3,并试图使用dropDups清除重复项,则会失败并出现此错误。为什么您的电子邮件看起来如此奇怪?电子邮件id的值是否实际上是由整数字符串键索引的子文档?或者它们是数组,这只是它们在编程语言中的表示形式?另外,您使用哪种语言?您需要提供更多信息。您提供的文件似乎不完整?“email_id”是否包含3个以上的元素?也许两份文件中重复了第46项内容?何时/如何添加索引?这是在脚本中还是在mongo shell中?正如@Sergei Tulentsev所说,您应该提供文档的完整视图。你能复制问题的最小代码集。@chakram88我尝试创建索引时,在集合中插入了两个文档。我曾尝试使用MongoShell和rockmongo管理面板创建索引,但出现了相同的错误。我不知道为什么我的电子邮件id在文档中显示为上面的样子。在集合中插入时,我的bson文档就像{email_id}一样简单me@mail.com}.你能粘贴db.users.findOne()的输出吗
来自mongo shell?我仍然不确定mongo是将其视为数组还是子文档。我认为确实如此。DropDup在mongo shell中工作,但在mongorock管理面板中失败。我阅读了erlang bson文档,其中说:“注意,字符串()将被解释为整数数组。必须以utf8二进制形式提供字符串,请参见下文。“-在这种情况下,我无法将我的电子邮件\u id保存为字符串,因为我希望电子邮件\u id字段作为一个整体字符串是唯一的,不需要每个字符的唯一性。这真的很混乱,我认为是来自erlang mongodb驱动程序,如果我以原子的形式传递我的email\u id字段,它将被保存为完整的字符串n,而不是如上所述的字符数组。啊,我明白了。那么这些实际上是错误编码为整数数组的字符串?在这种情况下,您应该确保按照文档中关于UTF8二进制文件的建议,将它们保存为MongoDB中的字符串。另外,您正在使用哪个驱动程序?我正在使用tony()的erlang mongodb驱动程序。。。实际上,如果字符串必须另存为字符串,则只需将字符串作为utf8二进制文件传递。。。如果以erlang列表的形式传递,它们将如上所示存储在代码段中,这将导致唯一密钥创建错误。我认为这个问题可以标记为接近。更多的是仔细阅读文档,并将字符串作为utf8二进制文件传递。我对Erlang了解不多,但听起来您必须使用将字符串转换为UTF-8字符串以存储在MongoDB中,否则驱动程序将其存储为代码点数组(即Int)。一旦您这样做,它将是mongo中的标量值,而不是数组,您将能够添加您的唯一索引。感谢every1,如果您正在使用erlang+mongodb,只需确保所有文档键都保存为erlang二进制项,以便mongodb按照文档中提到的方式提取它们。此外,最好(推荐)在任何时候(可能总是)以二进制形式(在进程之间)传递erlang消息和参数。。。
{
"_id" : ObjectId("4ef6d2641d41c83bdd000001"),
"email_id" : [
109,
97,
105,
108,
115,
102,
111,
114,
97,
98,
104,
105,
110,
97,
118,
64,
103,
109,
97,
105,
108,
46,
99,
111,
109
],
"display_name" : [
65,
98,
104,
105,
110,
97,
118,
43,
83,
105,
110,
103,
104
],
"provider" : [
106,
97,
120,
108,
46,
105,
109
],
"provider_id" : [ ]
}
db.users.find({email_id: 46})