mongoimport 失败与 "The _id field cannot be changed from" 不一致
mongoimport failing inconsistently with "The _id field cannot be changed from"
我在将数据导入 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?或者有没有
我没有看到一个问题。
我什至尝试更改 _id
中 s
和 a
的顺序,但问题仍然存在。
如果我尝试 运行 使用完全相同的数据文件多次执行完全相同的导入命令,则出现错误的文档会发生多次更改,并且有一次它按预期导入了所有行,但只有一次:
为了完整起见:我在 Mac OS X 10.10.5 上使用 mongo 3.0.5 由自制软件安装。
更新:
我已经与 mongoDB-Team 创建了一张工单:TOOLS-894
更新2:
我尝试不使用 _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
.
中属性的顺序
从 mongoimport 命令中删除 --upsert 将允许您导入数据。但这揭示了另一个更大的问题 - mongoimport 不会保留您的 _id 字段的键顺序。有时 s 先出现,有时 a。这会使涉及 _id 的每个应用程序操作都乏味且缓慢 - 你不能使用文档文字,你必须使用类似的东西:
db.coll.find({'_id.a': 5, '_id.s': NumberLong("38760488")})
使用嵌入式文档作为 _id 似乎是一种极端情况,没有与此相关的 jira 问题。 _id 类型可以是除数组之外的任何内容,因此它们适用于此用例。批量操作使用与标准写入操作不同的机制,所以......可能是一个错误 - 没有其他人这样做并发现它了吗?
您可能可以使用单独的写入命令(然后使用文档文字作为查询参数)来解决这个问题 - 但您应该这样做吗?无法使用 mongo export/import 进行数据库维护对我来说似乎是一个交易杀手。
另请注意:mongoimport --upsert 将用 "someKey":"someValue" 替换任何现有文档 - 假设这只是一个简化的测试用例。
您可以前往 https://jira.mongodb.org 并注册一个帐户来报告错误。
我尝试过的所有事情都让我相信这是 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-894 和 TOOLS-899 中,mongodb 开发人员描述了另一种解决方法:您可以使用 2.6 版本的 mongoimport,它没有这个错误。或者你可以等待 mongodb 3.0.7 应该包含修复。
更新 2:
MongoDB 的新版本解决了这个问题并按预期工作。
我在将数据导入 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?或者有没有
我没有看到一个问题。
我什至尝试更改 _id
中 s
和 a
的顺序,但问题仍然存在。
如果我尝试 运行 使用完全相同的数据文件多次执行完全相同的导入命令,则出现错误的文档会发生多次更改,并且有一次它按预期导入了所有行,但只有一次:
为了完整起见:我在 Mac OS X 10.10.5 上使用 mongo 3.0.5 由自制软件安装。
更新: 我已经与 mongoDB-Team 创建了一张工单:TOOLS-894
更新2:
我尝试不使用 _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
.
从 mongoimport 命令中删除 --upsert 将允许您导入数据。但这揭示了另一个更大的问题 - mongoimport 不会保留您的 _id 字段的键顺序。有时 s 先出现,有时 a。这会使涉及 _id 的每个应用程序操作都乏味且缓慢 - 你不能使用文档文字,你必须使用类似的东西:
db.coll.find({'_id.a': 5, '_id.s': NumberLong("38760488")})
使用嵌入式文档作为 _id 似乎是一种极端情况,没有与此相关的 jira 问题。 _id 类型可以是除数组之外的任何内容,因此它们适用于此用例。批量操作使用与标准写入操作不同的机制,所以......可能是一个错误 - 没有其他人这样做并发现它了吗?
您可能可以使用单独的写入命令(然后使用文档文字作为查询参数)来解决这个问题 - 但您应该这样做吗?无法使用 mongo export/import 进行数据库维护对我来说似乎是一个交易杀手。
另请注意:mongoimport --upsert 将用 "someKey":"someValue" 替换任何现有文档 - 假设这只是一个简化的测试用例。
您可以前往 https://jira.mongodb.org 并注册一个帐户来报告错误。
我尝试过的所有事情都让我相信这是 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-894 和 TOOLS-899 中,mongodb 开发人员描述了另一种解决方法:您可以使用 2.6 版本的 mongoimport,它没有这个错误。或者你可以等待 mongodb 3.0.7 应该包含修复。
更新 2:
MongoDB 的新版本解决了这个问题并按预期工作。