2015-08-27 3 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, ​​о котором следует сообщить или уже известно? Или есть проблема, которую я не вижу.

Я даже попытался изменить порядок s и a в _id, но проблема остается неизменной.

Если я TRIE запустить ту же самую команду импорта с точно такими же файлов данных несколько раз документы с ошибками меняются и одно время импортируемого все строки, как и ожидалось, но только один раз:

enter image description here

Для полноты: я использую mongo 3.0.5 в Mac OS X 10.10.5, установленном доморощенным.

UPDATE: Я создал билет с MongoDB-Team: TOOLS-894

UPDATE2:

Я старался не использовать _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

yes upsert необходимо, потому что JSON-файл, который я получаю, представляет собой дамп из другой (не MongoDB) системы и содержит новые и обновленные документы, поэтому upsert является обязательным, поскольку без него он не сможет импортировать с помощью E11000 duplicate key error collection' – 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-894 и TOOLS-899 разработчиках MongoDB описывает другой обходной путь: Вы можете использовать mongoimport от 2.6 версии, у которого не было эта ошибка. Или вы можете дождаться mongodb 3.0.7, который должен содержать исправление.

UPDATE 2:

Новые версии MongoDB устранили эту проблему и работать, как ожидалось.

0

Удаление - перезагрузка из вашей команды mongoimport позволит вам импортировать данные. Но это показывает еще одну большую проблему - mongoimport не сохраняет ваш заказ ключа в поле _id. Иногда s на первом месте, иногда a. Это сделало бы каждую операцию приложения, вовлекающие _id утомительным и медленно - вы не можете использовать документ буквальным, вам придется использовать что-то вроде:

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

Используя встроенный документ как _id походит на случай края и там не относятся к вопросам, связанным с этим. Типы _id могут быть чем угодно, кроме массива, поэтому они предназначены для этого варианта использования. Массовые операции используют другой механизм, чем стандартные операции записи, поэтому ... вероятно, ошибка - никто другой не делает этого и не обнаружил его еще?

Возможно, вы можете обойти это, используя отдельные команды записи (а затем использовать литерал doc в качестве параметра запроса), но не так ли? Невозможность использования экспорта/импорта mongo для обслуживания db кажется для меня убийцей сделки.

Также обратите внимание: mongoimport --upsert заменит любой существующий документ «someKey»: «someValue» - если это просто упрощенная тестовая версия.

Вы можете перейти на https://jira.mongodb.org и зарегистрироваться для получения отчета об ошибке.

+0

, upsert необходим, потому что JSON-файл, который я получаю, является дампом из другой (не MongoDB) системы и содержит новые и обновленные документы, поэтому upsert является обязательным, поскольку без него он не сможет 'импорт с E11000 дубликатов ключевых ошибок коллекции'. Я постараюсь сообщить об этом как об ошибке, а также попытаться найти обходное решение – jigfox