Перейти к содержанию

Вставка документов

Вставка – основной метод добавления данных в MongoDB. Чтобы вставить один документ, используйте метод коллекции insertOne:

1
> db.movies.insertOne({"title" : "Stand by Me"})

insertOne добавит в документ ключ _id (если вы его не предоставили) и сохранит документ в MongoDB.

insertMany

Если вам нужно вставить несколько документов в коллекцию, можно использовать метод insertMany. Этот метод позволяет передавать массив документов в базу данных, что гораздо более эффективно, потому что ваш код не будет бегать в базу данных и обратно ради каждого документа, а вставит их все сразу.

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
> db.movies.drop()
true
> db.movies.insertMany([{"title" : "Ghostbusters"},
... {"title" : "E.T."},
... {"title" : "Blade Runner"}]);
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("572630ba11722fac4b6b4996"),
ObjectId("572630ba11722fac4b6b4997"),
ObjectId("572630ba11722fac4b6b4998")
]
}
> db.movies.find()
{ "_id" : ObjectId("572630ba11722fac4b6b4996"), "title" : "Ghostbusters" }
{ "_id" : ObjectId("572630ba11722fac4b6b4997"), "title" : "E.T." }
{ "_id" : ObjectId("572630ba11722fac4b6b4998"), "title" : "Blade Runner" }

Отправка десятков, сотен или даже тысяч документов за один раз может значительно ускорить процесс вставки.

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

Текущие версии MongoDB не принимают сообщения длиннее 48 МБ, поэтому существует ограничение на количество, которое можно поместить в одну массовую вставку. Если вы попытаетесь вставить более 48 МБ, многие драйверы разделят вставку на несколько вставок по 48 МБ.

При выполнении массовой вставки с использованием метода insertMany, если документ посреди массива выдает какую-либо ошибку, что произойдет, зависит от того, выбрали ли вы упорядоченные или неупорядоченные операции. В качестве второго параметра insertMany можно указать документ опций. Укажите значение true для ключа ordered в документе параметров, чтобы обеспечить вставку документов в том порядке, в котором они были предоставлены. Укажите значение false, и MongoDB может изменить порядок вставок для повышения производительности. Упорядоченные вставки используются по умолчанию, если порядок не указан. В случае с упорядоченными вставками массив, переданный в insertMany, определяет порядок вставки. Если документ вызывает ошибку вставки, ни один документ за пределами этой точки в массиве не будет вставлен. В случае с неупорядоченными вставками MongoDB попытается вставить все документы независимо от того, приводят ли некоторые вставки к ошибкам.

В этом примере, поскольку упорядоченные вставки используются по умолчанию, будут вставлены только первые два документа. Третий документ выдаст ошибку, потому что нельзя вставить два документа с одинаковым _id:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
> db.movies.insertMany([
... {"_id" : 0, "title" : "Top Gun"},
... {"_id" : 1, "title" : "Back to the Future"},
... {"_id" : 1, "title" : "Gremlins"},
... {"_id" : 2, "title" : "Aliens"}])
2019-04-22T12:27:57.278-0400 E QUERY [js] BulkWriteError: write
error at item 2 in bulk operation :
BulkWriteError({
"writeErrors" : [
{
"index" : 2,
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection:
test.movies index: _id_ dup key: { _id: 1.0 }",
"op" : {
"_id" : 1,
"title" : "Gremlins"
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
BulkWriteError@src/mongo/shell/bulk_api.js:367:48
BulkWriteResult/this.toError@src/mongo/shell/bulk_api.js:332:24
Bulk/this.execute@src/mongo/shell/bulk_api.js:1186:23
DBCollection.prototype.insertMany@src/mongo/shell/crud_api.js:314:5
@(shell):1:1

Если вместо этого мы указываем неупорядоченные вставки, первый, второй и четвертый документы в массиве вставляются. Единственная неудачная вставка – третий документ, опять же по причине дублирующейся ошибки _id:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
> db.movies.insertMany([
... {"_id" : 3, "title" : "Sixteen Candles"},
... {"_id" : 4, "title" : "The Terminator"},
... {"_id" : 4, "title" : "The Princess Bride"},
... {"_id" : 5, "title" : "Scarface"}],
... {"ordered" : false})
2019-05-01T17:02:25.511-0400 E QUERY [thread1] BulkWriteError: write
error at item 2 in bulk operation :
BulkWriteError({
"writeErrors" : [
{
"index" : 2,
"code" : 11000,
"errmsg" : "E11000 duplicate key error index: test.movies.$_id_
dup key: { : 4.0 }",
"op" : {
"_id" : 4,
"title" : "The Princess Bride"
}
}
],
"writeConcernErrors" : [ ],
"nInserted" : 3,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
BulkWriteError@src/mongo/shell/bulk_api.js:367:48
BulkWriteResult/this.toError@src/mongo/shell/bulk_api.js:332:24
Bulk/this.execute@src/mongo/shell/bulk_api.js:1186.23
DBCollection.prototype.insertMany@src/mongo/shell/crud_api.js:314:5
@(shell):1:1

Если вы внимательно изучите эти примеры, то можете заметить, что выходные данные двух этих вызовов insertMany намекают на то, что в случае с массовыми записями могут поддерживаться и другие операции, помимо простых вставок. Хотя метод insertMany не поддерживает операции, отличные от вставки, MongoDB поддерживает специальный API, который позволяет группировать некое число операций разных типов в одном вызове.

Проверка вставки

MongoDB выполняет минимальные проверки вставляемых данных: она проверяет базовую структуру документа и добавляет поле _id, если оно не существует. Одной из проверок базовой структуры является размер: все документы должны быть меньше 16 МБ. Это несколько произвольный предел (и может быть повышен в будущем); в основном это предназначено для предотвращения неправильного проектирования схемы и обеспечения стабильной производительности. Чтобы увидеть двоичный бинарный размер JSON(BSON)-документа doc в байтах, выполните функцию Object.bsonsize(doc) из оболочки.

Чтобы у вас было представление о том, сколько данных составляет 16 МБ, весь текст романа «Война и мир» составляет всего 3,14 МБ.

Эти минимальные проверки также означают, что довольно просто вставить неверные данные (если вы пытаетесь это сделать). Таким образом, нужно разрешать только надежные источники, такие как серверы приложений, для подключения к базе данных. Все драйверы MongoDB для основных языков (и большинство второстепенных тоже) проверяют различные недействительные данные (документы, которые слишком большие, содержат строки в кодировке, отличной от UTF-8, или используют нераспознанные типы), перед тем как отправить что-либо в базу данных.

insert

До появления версии MongoD 3.0 insert был основным методом вставки документов в MongoDB. Драйверы MongoDB представили новый CRUD API одновременно с выпуском сервера MongoDB 3.0. Начиная с версии 3.2 оболочка mongo тоже поддерживает этот API, который включает в себя методы insertOne и insertMany, а также несколько других методов. Цель текущего CRUD API – сделать семантику всех операций CRUD согласованными и понятными для драйверов и оболочки. Хотя такие методы, как insert, по-прежнему поддерживаются ради обратной совместимости, их не следует использовать в будущих приложениях. Вместо этого стоит отдать предпочтение методам insertOne и insertMany для создания документов.

Комментарии