Mongodb dump (фильтрация документов и полей) - PullRequest
0 голосов
/ 26 ноября 2018

Я хочу сделать частичный дамп базы данных Mongodb ( частичный , как в, мне нужно отфильтровать некоторые документы и некоторые поля ).Затем этот дамп будет импортирован на другой сервер.

Я не могу использовать утилиту mongodump , так как она не позволяет фильтровать поля.
Я могу использовать mongoexport утилита, так как позволяет фильтровать как документы, так и поля.Тем не менее, в документации говорится, что mongoexport может выводить только файл JSON и:

не позволяет надежно сохранить все типы данных BSON с расширенными возможностями, поскольку JSON может представлять только подмножество типовподдерживается BSON.

  1. Я нахожу это утверждение немного расплывчатым, и я не совсем понимаю его.Итак, что именно произойдет, если я дам свою базу данных в JSON?Какие риски я могу запустить?Рискну ли я потерять некоторые документы?
  2. Если вы считаете, что мне следует полностью избегать использования mongoexport в производстве, могу ли я написать свое собственное приложение Nodejs для фильтрации и вывода дампа в BSON?Или это было бы невозможно?

1 Ответ

0 голосов
/ 26 ноября 2018

Можно использовать Представления , не прибегая к написанию низкоуровневого чтения для чтения и записи содержимого BSON.Есть также опции, которые на самом деле сохраняют тип даже при использовании форматов JSON, и вам даже не нужен «View» для этого.

Использование представлений с mongodump

Основная предпосылка - создать представление, которое возвращает только тот контент, который вы хотите.Представление может быть результатом любого выражения конвейерного агрегации.

Например, если задан простой документ в коллекции:

db.test.insert({ "a": 1, "b": 2, "c": 3 })

Вы можете создать представление в этой коллекции с помощью только требуемогополя:

db.test.createView("testView", "test", [{ "$project": { "a": 1, "b": 2 } }])

Затем, выйдя из оболочки монго, вы можете получить доступ к View из mongodump, используя опцию --viewsAsCollections:

mongodump --db test --collection testView --viewsAsCollections

Экспортирует только названную "коллекцию" (фактически только представление).--viewsAsCollections означает, что вместо mongodump, просто возвращающего определение представления (являющегося по сути конвейером агрегации), он возвращает результаты, как если бы это была настоящая коллекция.

Полученное содержимое BSON затем можно загрузить с помощью mongorestore:

mongorestore --db other --collection test

Затем содержимое из дампа BSON фактически записывается в новую цель базы данных хоста.вы соединяетесь с указанным именем коллекции

use other
db.test.find()

{ "_id" : ObjectId("5bfb3e0eadd1d8af906ad140"), "a" : 1, "b" : 2 }

и отмечаете также, что в качестве View конвейер агрегации может быть действительно чем угодно, поэтому операторы $match могут фильтровать, и вы можетепреобразуйте или даже фактически «агрегируйте» как хотите.

Используя Представления или --fields с mongoexport

Во многом таким же образом утилита mongoexportможет также получить доступ к содержимому из View.

Несмотря на то, что это не "строгий BSON" , на самом деле существует стандарт с MongoDB, который фактически сохраняет данныетипы.Это на самом деле описано в документации под MongoDB с расширенным JSON .

Так что это НЕ двоичный формат, и, поскольку JSON требует значительно больше места для хранения, но необходимая информация действительно есть.

Например:

db.mixed.insert({
  "a": NumberLong(1),
  "b": NumberDecimal("123.45"),
  "c": new Date(),
  "d":  "unwanted"
})

Что будет отображаться в оболочке mongo как:

{
        "_id" : ObjectId("5bfb428790b2b4e4241a015c"),
        "a" : NumberLong(1),
        "b" : NumberDecimal("123.45"),
        "c" : ISODate("2018-11-26T00:47:03.033Z"),
        "d" : "unwanted"
}

Вы все еще можете настроить представление:

db.createView("mixedView", "mixed", [{ "$project": { "a": 1, "b": 1, "c": 1 } }])

И экспорт просто заберет данные:

mongoexport --db test --collection mixedView > out.json

{
        "_id": {
                "$oid": "5bfb428790b2b4e4241a015c"
        },
        "a": {
                "$numberLong": "1"
        },
        "b": {
                "$numberDecimal": "123.45"
        },
        "c": {
                "$date": "2018-11-26T00:47:03.033Z"
        }
}

Или то же самое в исходной коллекции, просто используя --fields для выбора:

mongoexport --db test --collection mixed --fields a,b,c > out.json

С точно таким же выходом.Поскольку единственным ограничением является --query, может поддерживаться только регулярное выражение запроса, заданное find() или аналогичным.Это не так гибко, как View , но может выполнять элементарную фильтрацию для большинства потребностей.

Формат Extended JSON распознается mongoimport и есть также реализации синтаксических анализаторов, доступных для многих языков, которые также распознают это, и по мере чтения содержимого оно вставляется в целевую коллекцию с сохранением информации "type" :

mongoimport --db other --collection mixed out.json

И затем просмотр данных:

use other
db.mixed.findOne()
{
        "_id" : ObjectId("5bfb428790b2b4e4241a015c"),
        "a" : NumberLong(1),
        "b" : NumberDecimal("123.45"),
        "c" : ISODate("2018-11-26T00:47:03.033Z")
}

Так что это возможно, и существует формат Extended JSON для обмена данными в ситуациях, когда отправка двоичного файла контент может быть нежизнеспособным или даже нежелательным, но сохранение "типа" информации желательно .


В целом, существует множество вариантов, которые вы можетеиспользовать без необходимости возвращаться к чтению и записи двоичных форматов BSON или любого другого сложного двоичного формата для хранения данных между передачами.

В качестве примечания к "расплывчатому" отрывку фактические поддерживаемые типы BSON перечислены на странице Extended JSON документации.Вы можете даже сравнить это с BSON Specification , чтобы увидеть, что, несмотря на "осторожный" оператор, общие типы данных, которые вы действительно будете использовать, фактически все поддерживаются там,Хотя некоторые внешние интерпретации этой спецификации могут не соответствовать ALL из них, такие утилиты, как mongoexport и mongoimport, действительно совместимы.

...