Microsoft Cosmosdb для Mongodb: объединение необработанной коллекции в сегментированную

У меня есть 2 коллекции похожих документов (то есть один и тот же объект, разные значения). Одна коллекция (X) не сегментирована в базе данных A, другая коллекция (Y) сегментирована и находится внутри базы данных B. Когда я пытаюсь скопировать коллекцию X в базу данных B, я получаю сообщение об ошибке: «Общая коллекция пропускной способности должна иметь ключ раздела». Я также пробовал копировать данные с помощью вставки foreach, но это занимает слишком много времени.

Итак, мой вопрос: как я могу эффективно добавить данные из коллекции X в коллекцию Y?

Версия Mongodb в CosmosDB - 3.4.6.


person TimGT    schedule 06.01.2020    source источник
comment
Вы знаете, имеют ли две коллекции разные наборы значений полей _id?   -  person prasad_    schedule 07.01.2020


Ответы (3)


Вы можете выполнить агрегирование и добавить оператор $merge на последнем этапе.

| $merge                                | $out                                       | 
| Can output to a sharded collection.   | Cannot output to a sharded collection.     | 
| Input collection can also be sharded. | Input collection, however, can be sharded. | 

https://docs.mongodb.com/manual/reference/operator/aggregation/merge/#comparison-with-out

person Valijon    schedule 06.01.2020
comment
Есть ли альтернатива команде $ merge? Использование cosmosdb, поддерживающего mongodb до версии 3.4. На самом деле, мне нужно что-то похожее на команду SQL Union, которая будет добавлять данные из коллекции B в коллекцию A. О да, cosmosdb не поддерживает mongoimport, потому что он предоставляет свою собственную службу миграции. - person TimGT; 15.01.2020

Итак, мой вопрос: как я могу эффективно добавить данные из коллекции X в коллекцию Y?

Серверные инструменты mongodump и mongorestore. Вы можете экспортировать данные исходной коллекции в файлы дампа BSON и импортировать в целевую коллекцию. Эти процессы выполняются очень быстро, поскольку данные в базе данных уже находятся в формате BSON.

С помощью этих инструментов данные можно экспортировать из не сегментированной коллекции в сегментированную коллекцию. В этом случае требуется, чтобы в исходной коллекции было поле ключа осколка (или поля) со значениями. Обратите внимание, что индексы из исходной коллекции также экспортируются и импортируются (с помощью этих инструментов).

Вот пример рассматриваемого сценария:

mongodump --db=srcedb --collection=srcecoll --out="C:\mongo\dumps"

Это создает каталог дампа с именем базы данных. В нем будет файл srcecoll.bson, который используется для импорта.

mongorestore --port 26xxxx --db=trgtdb --collection=trgtcoll --dir="C:\mongo\dumps\srcecoll.bson"

Хост / порт подключается к mongos сегментированного кластера. Обратите внимание, что имя файла bson необходимо указать в параметре --dir.

Импорт добавляет данные и индексы в существующую сегментированную коллекцию. Процесс только вставляет данные; существующие документы не могут быть обновлены. Если значение _id из исходной коллекции уже существует в целевой коллекции, процесс не перезапишет документы (и эти документы не будут импортированы, и это не является ошибкой).

Для mongorestore есть несколько полезных опций, например: --noIndexRestore и --dryRun.

person prasad_    schedule 07.01.2020
comment
спасибо за ваш ответ, но cosmosdb не поддерживает mongorestore, потому что он предоставляет собственную службу миграции. И эти службы не могут добавлять данные в существующую коллекцию. Он может только перезаписать - person TimGT; 15.01.2020
comment
Насколько велика исходная коллекция? - person prasad_; 15.01.2020
comment
он большой, поэтому использовать вставку и массовую вставку не получится. размер составляет около 7 ГБ. Есть идеи, как объединить данные без $ merge и вставить массив? - person TimGT; 16.01.2020

Поскольку версия MongoDb в CosmosDB в настоящее время 3.4.6, она не поддерживает $ merge и множество других команд, таких как colleciton.copyTo и т. Д. Использование функции импорта Studio 3T также не помогло.

Решение, которое я использую, - загрузить целевую коллекцию на мой локальный mongodb, очистить ее, а затем написать Java-код, который будет читать мои чистые данные из локальной базы данных и вставлять (или записывать) их в целевую коллекцию. Таким образом, данные будут добавлены в целевую коллекцию. Скорость, которую я измерил, составила 2 часа для 1 млн документов (~ 750 МБ), конечно, эти цифры могут варьироваться в зависимости от различных факторов, например сети, размера документа и т. Д.

person TimGT    schedule 21.01.2020