#javascript #mongodb #date #mongodb-query #isodate
#javascript #mongodb #Дата #mongodb-запрос #isodate
Вопрос:
Моя коллекция MongoDB выглядит следующим образом:
[
{
"id": "myid",
"field": {
"total": 1,
"subfield": [
{
"time": "2020-08-06T08:33:57.977 0530"
},
{
"time": "2020-05-08T04:13:27.977 0530"
}
]
}
},
{
"id": "myid2",
"field": {
"total": 1,
"subfield": [
{
"time": "2020-07-31T10:15:50.184 0530"
}
]
}
}
]
Мне нужно обновить все документы и преобразовать строку даты в поле, time
доступном в subfield
массиве, в формат даты ISO MongoDB.
У меня тысячи документов и сотни объектов в subfield
массиве
Я знаю о агрегатной функции $todate
и $convert
. Но я не хочу использовать агрегацию, потому что,
-
Чтобы использовать
$todate
or$convert
, мне нужно размотатьfield.subfield
массив, что опять же является дорогостоящей операцией. -
Я хочу обновить свой документ и сохранить его в формате даты.
Версия моего сервера MongoDB: 4.0.3
Я попробовал следующее, но, похоже, это не работает, а также не возвращает никаких ошибок.
db.collection.find().forEach(function(doc) {
doc.field.subfield.time=new ISODate(doc.field.subfield.time);
db.collection.save(doc);
})
Комментарии:
1. Платформа агрегации поддерживает обновления с помощью $ merge.
2. Спасибо, что указали. Но это доступно только с версии 4.2. Моя версия 4.0 @D.SM
3. Это всего лишь одноразовая операция?
4. да @WernfriedDomscheit
5. Если у вас тысячи документов, это не должно быть проблемой. В случае миллионов документов, которые могут вас беспокоить
Ответ №1:
Вы пропустили цикл для subfield
, потому что это массив,
db.collection.find().forEach(function(doc) {
doc.field.subfield.forEach(function(r) {
r.time = new ISODate(r.time);
})
db.collection.save(doc);
})
Если это на один раз, то время не имеет значения, я думаю, что оба варианта займут одинаковое время, если вы выполняете агрегацию или forEach.
Если вы планируете обновить версию MongoDB, тогда сформируйте 4.2, вариант, который вы можете обновить с помощью updateMany()
использования конвейера обновления с агрегацией,
db.collection.updateMany({},
[{
$set: {
"field.subfield": {
$map: {
input: "$field.subfield",
as: "r",
in: {
$mergeObjects: [
"$$r",
{ time: { $toDate: "$$r.time" } }
]
}
}
}
}
}]
)