$replaceAll (聚合)
定义
$replaceAll
将输入字符串中所有搜索字符串的实例替换为替换字符串。
$replaceAll
是大小写敏感的,并且对集合上存在的任何排序规则不敏感。
语法
$replaceAll
操作符有以下操作符表达式语法:
{ $replaceAll: { input: <expression>, find: <expression>, replacement: <expression> } }
操作符字段
行为
输入的 input、find 和 replacement 表达式必须评估为字符串或 null
,否则 $replaceAll
将引发错误。
$replaceAll
和空值
如果 input 或 find 指向一个缺失的字段,它们将返回 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
和校对
对于所有 $replaceAll
表达式的字符串匹配始终是大小写敏感和重音敏感的。当使用 $replaceAll
进行字符串比较时,忽略在集合、校对、db.collection.aggregate()
或索引上配置的任何校对。
例如,创建一个具有校对强度 1
的示例集合
db.createCollection( "myColl", { collation: { locale: "fr", strength: 1 } } )
校对强度为 1
仅比较基字符,并忽略其他差异,例如大小写和重音。
接下来,插入三个示例文档
db.myColl.insertMany([ { _id: 1, name: "cafe" }, { _id: 2, name: "Cafe" }, { _id: 3, name: "café" } ])
以下 $replaceAll
操作尝试在 name
字段中查找并替换所有 "Cafe" 的实例
db.myColl.aggregate([ { $addFields: { resultObject: { $replaceAll: { input: "$name", find: "Cafe", replacement: "CAFE" } } } } ])
由于 $replaceAll
忽略了此集合的校对配置,因此操作仅在文档 2
中匹配 "Cafe" 的实例
{ "_id" : 1, "name" : "cafe", "resultObject" : "cafe" } { "_id" : 2, "name" : "Cafe", "resultObject" : "CAFE" } { "_id" : 3, "name" : "café", "resultObject" : "café" }
尊重校对的运算符,如 $match
,由于此集合的校对强度为 1
,因此会在与 "Cafe" 进行字符串比较时匹配所有三个文档。
$replaceAll
和 Unicode 标准化
$replaceAll
聚合表达式不执行任何 Unicode 正规化。这意味着所有 $replaceAll
表达式的字符串匹配将考虑在 Unicode 中表示字符时使用的代码点数量以进行匹配。
例如,字符 é
可以使用一个或两个代码点来表示
Unicode | 显示为 | 代码点 |
---|---|---|
\xe9 | é | 1 ( \xe9 ) |
e\u0301 | é | 2 ( e + \u0301 ) |
使用 $replaceAll
与一个 查找 字符串,其中字符 é
使用一个代码点表示 Unicode,将不会匹配 输入 字符串中使用两个代码点表示的任何 é
实例。
以下表格显示了当与 输入 字符串进行比较时,当 é
使用一个或两个代码点表示时,"café" 的 查找 字符串是否匹配。此示例中使用的 查找 字符串使用一个代码点表示 é
字符
示例 | 匹配 |
---|---|
{ $replaceAll: { input: "caf\xe9", find: "café", replacement: "CAFE" } } | 是 |
{ $replaceAll: { input: "cafe\u0301", find: "café", replacement: "CAFE" } } | 否 |
因为 $replaceAll
不执行任何 Unicode 正规化,所以只有第一个字符串比较匹配,其中 查找 和 输入 字符串都使用一个代码点来表示 é
。
示例
创建一个包含以下文档的 库存
集合
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" }, ])
以下示例将 item
字段中的每个 "blue paint" 实例替换为 "red paint"
db.inventory.aggregate([ { $project: { item: { $replaceAll: { input: "$item", find: "blue paint", replacement: "red paint" } } } } ])
操作返回以下结果
{ "_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" }