1) Если вы используете версию MongoDB> = 4.2
, попробуйте следующий запрос:
db.collection.update({'reviews.snid' : {$exists : true}}, [
{
$set: {
reviews: {
$map: { input: "$reviews", in: { 'snid': { $toInt: "$$this.snid" } } }
}
}
}
],{multi :true})
Вышеупомянутый запрос использует Агрегирующий конвейер в .update()
, который был представлен в версии 4.2
, Вы также можете использовать .updateMany()
вместо .update()
.
Работает с документами следующего типа:
/* 1 */
{
"_id" : ObjectId("5e810f5ec16b5679b43a2f0e"),
"reviews" : [
{
"snid" : '1242'
},
{
"snid" : '8392'
}
]
}
/* 2 */
{
"_id" : ObjectId("5e810f6ac16b5679b43a310c"),
"reviews" : [
{
"snid" : '1242232'
},
{
"snid" : '8391232'
}
]
}
/* 3 */
{
"_id" : ObjectId("5e8110b1c16b5679b43a5148"),
"abc" : 1
}
/* 4 */
{
"_id" : ObjectId("5e8110c3c16b5679b43a52f9"),
"reviews" : []
}
/* 5 */
{
"_id" : ObjectId("5e811359c16b5679b43a9229"),
"reviews" : [
{
"abc" : "1"
}
]
}
Но приведенный выше запрос на обновление будет частично работать, если вы делаете c, как показано ниже:
{
"_id" : ObjectId("5e811359c16b5679b43a9230"),
"reviews" : [
{
"abc" : "1"
},
{
"snid" : "123"
}
]
}
В этом случае вам нужно использовать $ cond , чтобы сделать условная проверка в $map
, чтобы увидеть, есть ли у текущего объекта ключ snid , затем преобразовать значение или передать тот же объект, что и в массив 'reviews'.
2) На всякий случай, если ваша версия MongoDB <<code>4.2 / 4.0
&> 3.2
- Вы можете использовать .bulkWrite () :
Причина, по которой вы не можете использовать Агрегационный конвейер в обновлении и также $ toInt . Поэтому вам нужно сделать .find()
, чтобы получить целые документы и написать код, чтобы преобразовать их из строк в целые числа, и использовать .bulkWrite()
, чтобы обновить документы за один вызов обновления БД (вы можете взять _id
в качестве ключа для каждого документа).
3) Вы также можете написать запрос агрегации для существующей коллекции и использовать $ out для обновления всей коллекции или записи результата агрегации в новую коллекцию, выполнив всего один запрос. Я бы предпочел временно записать его в новую коллекцию, чтобы проверить правильность данных и переименовать новую коллекцию в существующую, назвав существующую чем-то, заканчивающимся _backup
, используемым в качестве резервной копии.