mongoimport与“_id字段无法更改”

时间:2015-08-27 15:31:07

标签: json mongodb mongoimport

我在将数据导入mongodb时遇到问题。我有一个test.json这样的文件:

{"_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。

更新: 我用mongoDB-Team创建了一个Ticket: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中属性的顺序。

2 个答案:

答案 0 :(得分:0)

从mongoimport命令中删除--upsert将允许您导入数据。但这揭示了另一个更大的问题 - mongoimport不会保留你的_id字段的密钥排序。有时s首先出现,有时候出现。这会使涉及_id的每个应用程序操作都变得乏味和缓慢 - 你不能使用文档文字,你必须使用类似的东西:

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

将嵌入文档用作_id似乎是一个边缘案例,并且没有与此相关的jira问题。 _id类型可以是除数组之外的任何类型,因此它们适用于此用例。批量操作使用与标准写入操作不同的机制,因此......可能是一个错误 - 没有其他人这样做并发现它了吗?

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

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

您可以转到https://jira.mongodb.org并注册帐户以报告错误。

答案 1 :(得分: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

插入此新文档并更新旧文档

<强>更新

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

更新2

MongoDB的新版本解决了这个问题并按预期工作。