Definition定义
$replaceAllReplaces all instances of a search string or regex pattern in an input string with a replacement string.用替换字符串替换输入字符串中搜索字符串或正则表达式模式的所有实例。$replaceAllis both case-sensitive and diacritic-sensitive, and ignores any collation present on a collection.区分大小写和变音符号,并忽略集合上存在的任何排序规则。
Syntax语法
The $replaceAll operator has the following operator expression syntax:$replaceAll运算符具有以下运算符表达式语法:
{ $replaceAll: { input: <expression>, find: <expression>, replacement: <expression> } }
Operator Fields运算符字段
input |
|
find |
|
replacement |
|
Behavior行为
The input, find, and replacement expressions must evaluate to a string or a null (or regex for find), or $replaceAll fails with an error.input、find和replacement表达式的计算结果必须为字符串或null(或find的正则表达式),否则$replaceAll将失败并出现错误。
$replaceAll and Null Values和null值
If input or find refer to a field that is missing, they return 如果null.input或find引用了缺失的字段,则返回null。
If any one of input, find, or replacement evaluates to a 如果null, the entire $replaceAll expression evaluates to null:input、find或replacement中的任何一个计算结果为null,则整个$replaceAll表达式计算结果为null:
{ $replaceAll: { input: null, find: "abc", replacement: "ABC" } } | null |
{ $replaceAll: { input: "abc", find: null, replacement: "ABC" } } | null |
{ $replaceAll: { input: "abc", find: "abc", replacement: null } } | null |
$replaceAll and Collation$replaceAll和排序
String matching for $replaceAll expressions is always case-sensitive and diacritic-sensitive. Any collation configured is ignored when performing string comparisons with $replaceAll.$replaceAll表达式的字符串匹配始终区分大小写和变音符号。使用$replaceAll执行字符串比较时,将忽略配置的任何排序规则。
For example, create a sample collection with collation strength 例如,创建排序强度为1:1的样本集合:
db.createCollection( "restaurants", { collation: { locale: "fr", strength: 1 } } )
A collation strength of 排序强度为1 compares base character only and ignores other differences such as case and diacritics.1时,仅比较基本字符,忽略其他差异,如大小写和变音符号。
Next, insert example documents:接下来,插入示例文档:
db.restaurants.insertMany( [
{ _id: 1, name: "cafe" },
{ _id: 2, name: "Cafe" },
{ _id: 3, name: "café" }
] )
The following 以下$replaceAll operation tries to find and replace all instances of "Cafe" in the name field:$replaceAll操作尝试查找并替换name字段中“Cafe”的所有实例:
db.restaurants.aggregate( [
{
$addFields:
{
resultObject: {
$replaceOne: {
input: "$name",
find: "Cafe",
replacement: "CAFE"
}
}
}
}
] )
{ "_id" : 1, "name" : "cafe", "resultObject" : "cafe" }
{ "_id" : 2, "name" : "Cafe", "resultObject" : "CAFE" }
{ "_id" : 3, "name" : "café", "resultObject" : "café" }
Because 由于$replaceAll ignores the collation configured for this collection, the operation only matches the instance of "Cafe" in document 2:$replaceAll忽略了为此集合配置的排序规则,因此该操作仅匹配文档2中的“Cafe”实例:
{ _id: 1, name: "cafe", resultObject: "cafe" }
{ _id: 2, name: "Cafe", resultObject: "CAFE" }
{ _id: 3, name: "café", resultObject: "café" }
Operators that respect collation, such as 由于此集合的排序强度为$match, would match all three documents when performing a string comparison against "Cafe" due to this collection's collation strength of 1.1,因此尊重排序规则的运算符(如$match)在与“Cafe”进行字符串比较时将匹配所有三个文档。
$replaceAll and Unicode NormalizationUnicode标准化
The $replaceAll aggregation expression does not perform any unicode normalization. This means that string matching for all $replaceAll expressions will consider the number of code points used to represent a character in unicode when attempting a match.$replaceAll聚合表达式不执行任何unicode规范化。这意味着,在尝试匹配时,所有$replaceAll表达式的字符串匹配都将考虑用于以unicode表示字符的码点数。
For example, the character 例如,字符é can be represented in unicode using either one code point or two:é可以用一个或两个码位以unicode表示:
| Unicode | ||
|---|---|---|
\xe9 | é | 1 ( \xe9 ) |
e\u0301 | é | 2 ( e + \u0301 ) |
Using 将$replaceAll with a find string where the character é is represented in unicode with one code point will not match any instance of é that uses two code points in the input string.$replaceAll与find字符串一起使用,其中字符é以unicode表示,只有一个码点,这将与input字符串中使用两个码点的任何é实例都不匹配。
The following table shows whether a match occurs for a find string of "café" when compared to input strings where 下表显示了与é is represented by either one code point or two. The find string in this example uses one code point to represent the é character:input字符串相比,find字符串“café”是否匹配,其中é由一个或两个代码点表示。本例中的find字符串使用一个代码点来表示é字符:
| Match | |
|---|---|
{ $replaceAll: { input: "caf\xe9", find: "café", replacement: "CAFE" } } | yes |
{ $replaceAll: { input: "cafe\u0301", find: "café", replacement: "CAFE" } } | no |
Because 因为$replaceAll does not perform any unicode normalization, only the first string comparison matches, where both the find and input strings use one code point to represent é.$replaceAll不执行任何unicode规范化,所以只有第一个字符串比较匹配,其中find和input字符串都使用一个代码点来表示é。
Examples示例
Create an 使用以下文档创建inventory collection with the following documents:inventory集合:
db.inventory.insertMany( [
{ _id: 1, item: "blue paint" },
{ _id: 2, item: "blue and green paint" },
{ _id: 3, item: "blue paint with blue paintbrush" },
{ _id: 4, item: "blue paint with green paintbrush" },
] )
Replace Using a String使用字符串替换
The following example replaces each instance of "blue paint" in the 以下示例将item field with "red paint":item字段中的每个“蓝色油漆”实例替换为“红色油漆”:
db.inventory.aggregate([
{
$project:
{
item: { $replaceAll: { input: "$item", find: "blue paint", replacement: "red paint" } }
}
}
])
The operation returns the following results:该操作返回以下结果:
{ _id: 1, item: "red paint" }
{ _id: 2, item: "blue and green paint" }
{ _id: 3, item: "red paint with red paintbrush" }
{ _id: 4, item: "red paint with green paintbrush" }Replace Using Regex使用正则表达式替换
The following example uses a regex pattern 以下示例使用正则表达式模式\\bblue paint\\b to replace each instance matching "blue paint" as a whole phrase in the item field with "red paint":\\bblue paint\\b将item字段中与“blue paint”匹配的每个实例替换为“red paint”:
db.inventory.aggregate([
{
$project:
{
item: { $replaceAll: { input: "$item", find: \\bblue paint\\b, replacement: "red paint" } }
}
}
])
The operation returns the following results:该操作返回以下结果:
{ _id: 1, item: "red paint" }
{ _id: 2, item: "blue and green paint" }
{ _id: 3, item: "red paint with blue paintbrush" }
{ _id: 4, item: "red paint with green paintbrush" }
In this case, "blue paint" is replaced only when it appears as a whole phrase, due to the use of regex word boundaries (在这种情况下,由于使用了正则表达式单词边界(\b), and not when it is a substring within a larger word.\b),只有当“blue paint”作为一个完整的短语出现时才会被替换,而当它是一个较大单词中的子字符串时则不会被替换。