В 1-м, 2-м и третьем выпусках ECMAScript использование переменных $ -prefixed переменных явно не поощрялось спецификацией, за исключением контекста автогенерированного кода:
Знак доллара (
blockquote>$
) и символ подчеркивания (_
) разрешены в любом месте идентификатора. Знак доллара предназначен для использования только в механически сгенерированном коде.Однако в следующей версии ([1] 5th Edition , которая является текущей), это ограничение было , а приведенный выше фрагмент заменен на
Знак доллара (
blockquote>$
) и знак подчеркивания (_
) разрешены в любом месте в IdentifierName .Таким образом, знак $ теперь может свободно использоваться в именах переменных. Определенные структуры и библиотеки имеют свои собственные условные обозначения о значении символа, отмеченные в других ответах здесь.
есть какая-то агрегированная или групповая операция, которая может сделать эту операцию проще / быстрее
blockquote>Вы можете запустить MongoDB Aggregation Pipeline для обработки поиска и заменить, затем перебрать результат и отправить неупорядоченные операции массового обновления .
Я напишу приведенные ниже примеры в mongo shell , чтобы сделать его универсальным, но для Mongoose см. - Model.aggregate () ] и Model.bulkWrite () для получения дополнительной информации.
Например, если у вас есть три документа, как показано ниже:
{ "_id": 1, "path": "a,b,c,d" } { "_id": 2, "path": "b,a,c,d" } { "_id": 3, "path": "c,b,a" }
Где вы хотели бы заменить
a
на1,2,3
. Используя конвейер агрегации, создайте новое поле с именемnewPath
для хранения замещенного результата, как показано ниже:db.collection.aggregate([ {"$addFields":{ "toBeRemoved": "a", "replacement": "1,2,3", }}, {"$addFields":{ "newPath": { "$concat":[ {"$substrBytes":[ "$path", 0, { "$cond": { "if": { "$lt": [ {"$subtract": [{"$strLenBytes": "$path"}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$indexOfBytes":["$path", "$toBeRemoved"]} ] } ]}, 0] }, "then": 0, "else": {"$subtract": [{"$strLenBytes": "$path"}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$indexOfBytes":["$path", "$toBeRemoved"]} ] } ]} } }]}, "$replacement", {"$substrBytes":[ "$path", {"$add":[{ "$cond": { "if": { "$lt": [ {"$subtract": [{"$strLenBytes": "$path"}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$indexOfBytes":["$path", "$toBeRemoved"]} ] } ]}, 0] }, "then": 0, "else": {"$subtract": [{"$strLenBytes": "$path"}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$indexOfBytes":["$path", "$toBeRemoved"]} ] } ]} } }, {"$strLenBytes": "$toBeRemoved"} ]}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$add": [ {"$indexOfBytes":["$path", "$toBeRemoved"]}, {"$strLenBytes": "$toBeRemoved"} ]} ]} ]} ] }, }}, {"$project": { "toBeRemoved":0, "replacement":0, }} ])
Это выведет что-то, как показано ниже:
{ "_id": 1, "path": "a,b,c,d", "newPath": "1,2,3,b,c,d" } { "_id": 2, "path": "b,a,c,d", "newPath": "b,1,2,3,c,d" } { "_id": 3, "path": "c,b,a", "newPath": "c,b,1,2,3" }
Обратите внимание, что Агрегация выше была написана так, чтобы ее можно было повторно использовать для другой замены. то есть заменили
toBeRemoved
наb
иreplacement
наx,y
, и это будет работать аналогично.Приведенный выше конвейер агрегации должен работать для MongoDB v3.4 +. Также стоит отметить, что в настоящее время существует открытый билет SERVER-11947 для добавления поддержки регулярных выражений в язык агрегации.
Затем можно выполнить итерацию по результату и отправить неупорядоченные
bulkWrite
операции обновления, с примером ниже:db.collection.bulkWrite( [ { "updateOne" : { "filter" : { "_id" : 1}, "update" : { "$set" : { "path" : <newPath value> } } } }, { "updateOne" : { "filter" : { "_id" : 2}, "update" : { "$set" : { "path" : <newPath value> } } } }, )