2015-08-27 23 views
3

我有问题导入数据到mongodb与。我有一个test.json文件是这样的:mongoimport不符合“_id字段不能改变”

{"_id":{"s":{"$numberLong":"38851448"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"38853194"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"38760498"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"39099662"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"38855558"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"38760487"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"38760488"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"39099663"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"38851450"},"a":5},"someKey":"someValue"} 
{"_id":{"s":{"$numberLong":"38853546"},"a":5},"someKey":"someValue"} 

我尝试使用以下命令将其导入:

mongoimport --type json --db test --collection coll --file test.json --upsert 

进口几乎总是失败,出现相同的错误消息:

2015-08-27T17:02:15.510+0200 error inserting documents: The _id field cannot be changed from {_id: { s: 38851448, a: 5 }} to {_id: { a: 5, s: 38851448 }}. 
2015-08-27T17:02:15.511+0200 error inserting documents: The _id field cannot be changed from {_id: { a: 5, s: 38760487 }} to {_id: { s: 38760487, a: 5 }}. 

这是令人沮丧的是,这个错误甚至不可重现。进口商似乎改变了_id的属性顺序,但我不知道为什么,这是一个应该报告或已知的BUG?或者有没有 有问题,我没有看到。

我甚至试图改变sa_id的顺序,但问题保持不变。

如果我索引树跑具有完全相同的数据文件中多次出现错误的文件发生变化,有一段时间,进口的所有行如预期完全相同的导入命令,但只是一个时间:

enter image description here

为了完整:我在Mac OS X 10.10.5上使用了mongo 3.0.5,并且安装了homebrew。

UPDATE: 我创建了一个票务与MongoDB的特攻队:TOOLS-894

UPDATE2

我尽量不使用_id但ID为我的唯一关键:

{"id":{"s":{"$numberLong":"38851448"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"38853194"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"38760498"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"39099662"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"38855558"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"38760487"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"38760488"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"39099663"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"38851450"},"a":5},"someKey":"someValue"} 
{"id":{"s":{"$numberLong":"38853546"},"a":5},"someKey":"someValue"} 

并将其与此导入:

mongoimport --type json --db test --collection coll --file test.json --upsertFields id 

现在我没有得到任何错误,但在两次导入后,我在集合中有15行而不是10个。再次因为id中的属性的顺序。

+1

好像'--upsert'标志导致了这个错误,是否需要你的情况。似乎mongo在尝试使用组合标识更新数据时会导致问题。 – cubbuk

+0

是的upsert是必要的,因为我得到的JSON文件是从另一个(非MongoDB)系统转储并包含新的和更新的文档,所以upsert是强制性的,因为如果没有它,它将无法用'E11000重复密钥错误收集' – jigfox

回答

0

所有的事情我试图使我相信,这是内mongoimport一个错误,我把它报告给mongoldb团队:TOOLS-894

那的工作对我的解决方法是移动的唯一密钥文件进行的_id并像这样把它分解到自己的属性:

{"s":{"$numberLong":"38851448"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"38853194"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"38760498"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"39099662"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"38855558"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"38760487"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"38760488"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"39099663"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"38851450"},"a":5,"someKey":"someValue"} 
{"s":{"$numberLong":"38853546"},"a":5,"someKey":"someValue"} 

这样我能够导入这样的数据:

mongoimport --type json --db test --collection coll --upsertFields a,s --file test.json 

与这个新的文件得到插入旧文件得到更新

UPDATE

TOOLS-894TOOLS-899 MongoDB的开发人员描述另一个解决方法:可以使用mongoimport从2.6版本,它不具有这个bug。或者你可以等待mongodb 3.0.7应该包含修复。

更新2:如预期

的MongoDB的新版本解决了这个问题而努力。

0

从mongoimport命令中删除--upsert将允许您导入数据。但是,这揭示了另一个更大的问题 - mongoimport不会保留您的_id字段的按键顺序。有时候s是第一个,有时候是a。这将使每一个应用程序的操作涉及_id繁琐和缓慢的 - 你不能使用文档文字,你将不得不使用这样的:

db.coll.find({'_id.a': 5, '_id.s': NumberLong("38760488")}) 

使用嵌入文档_id似乎是一个边缘的情况下,有没有与此相关的杰拉问题。 _id类型可以是任何数组,所以他们打算用于这个用例。批量操作使用与标准写入操作不同的机制,所以......可能是一个错误 - 没有其他人正在这样做并发现它?

你可以使用单独的写命令(然后使用doc文字作为查询参数)解决这个问题 - 但是你应该吗?不能使用Mongo导出/导入进行数据库维护对我来说似乎是一个交易杀手。

另请注意:mongoimport --upsert将用“someKey”替换任何现有的doc:“someValue” - 假设这只是一个简化的测试用例。

您可以前往https://jira.mongodb.org并注册一个帐户来报告错误。

+0

upsert是必要的,因为我得到的JSON文件是来自另一个(非MongoDB)系统的转储并包含新的和更新的文档,所以upsert是强制性的,因为如果没有它,它将无法使用E11000重复密钥错误集合导入。我将尝试将此报告为一个错误,并尝试找到解决方法 – jigfox