#mongodb #mongodb-query #replaceall
Вопрос:
{
"_id": ObjectId("60743bd0ffb98b1e7c215c1b"),
"orderId": "787968",
"notes":"Leave in porch"
"lineItems": [
{
"lineItemId": "1741547",
"channelLineItemId": "9741370294381",
"skuId": "XXX-YYY-x-PR-YYY"
},
{
"lineItemId": "1741549",
"channelLineItemId": "9741370359917",
"skuId": "XXX-YYY-x-PR-YYY"
},
{
"lineItemId": "1741551",
"channelLineItemId": "9741370425453",
"skuId": "XXX-YYY-x-P-YYY"
}
],
"Data": {
"email_status": "SENT",
"sent_date": ISODate("2021-04-12T12:23:48.623Z")
}
}
У меня в моем монго была коллекция данных о порядке с вышеуказанной структурой.
Мне нужно заменить все -PR-
и -PG-
простым дефисом -
во всех записях и во всех элементах строк. т. е. ему нужно перебрать все записи и все элементы массива. если я использую команду SQL, я буду использовать
update line_item set sku_id = replace(sku_id , '-PR-','-');
после выполнения команды XYZ-BCD-X-PR-ZAB будет XYZ-BCD-X-AB
Я знаю, как обновить элементы за пределами массива, если я пытаюсь заменить команду в заметках, которые я могу использовать
db.orderData.find().forEach(function(doc) {
doc.note : doc.note.replace('-PG-', '-');
db.orderData.save(doc);
});
Я не знаю, как использовать то же самое при обновлении в массиве
Я пытался
db.orderData.find({orderId : "787968"}).forEach(function(doc) {
doc.lineItems.$.skuId : doc.lineItems.$.skuId.replace('-PG-', '-');
db.orderData.save(doc);
});
но это не работает.
Кто-нибудь, пожалуйста, помогите мне и заранее спасибо.
Комментарии:
1. в каких областях вы хотите это сделать? только в
skuId
?
Ответ №1:
Вы можете сделать это, поместив конвейер агрегации в update
:
- использовать
$addFields
в$map
lineItems
массиве; - используйте
$replaceAll
$map
для замены-PR — на — - повторите шаг 2 для замены-PG — на *— на другом
$addFields
этапе
Вот игровая площадка Монго для вашей справки.
Обновление как OP с использованием Mongo DB 3.6
Поскольку $replaceAll
доступно только начиная с Mongo DB 4.4, $replaceAll
его можно было бы заменить приведенным ниже обходным решением:
$split
по-PR-
или-PG-
разбить на массив сегментов- присоединитесь к массиву
$reduce
и{$concat: ["$$value","-","$$this"]}
- В этом случае в поле будут введены 2 дополнительных дефиса
$concat
. Используйте$substrCP
, чтобы вырезать 2 дефиса заголовка.
Вот игровая площадка Монго для вашей справки.
Комментарии:
1. он может стать меньше с картой за 1 доллар, я думаю так
2. Спасибо @Takis_, это хорошая мысль. Я думаю, что ОП должен использовать вашу краткую версию в своем реальном коде. Я бы просто сохранил свою немного утомительную версию для демонстрационных целей здесь.
3. мой монго-версия 3.6, я думаю, что функция replaceAll недоступна в этой версии. есть ли какая-либо функция, которая может поддерживать эту версию 3.6
4. Я обновил ответ альтернативой, используя
$split
,$concat
,$reduce
,$strLenCP
, которая должна быть доступна в MongoDB 3.6