$replaceAll (aggregation)

On this page本页内容

Definition定义

$replaceAll

New in version 4.4.版本4.4中的新功能。

Replaces all instances of a search string in an input string with a replacement string.用替换字符串替换输入字符串中搜索字符串的所有实例。

$replaceAll is 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运算符字段

Field字段Description描述
input

The string on which you wish to apply the find. 要对其应用find的字符串。Can be any valid expression that resolves to a string or a null. 可以是解析为字符串或null的任何有效表达式If input refers to a field that is missing, $replaceAll returns null.如果input引用的字段丢失,$replaceAll返回null

find

The string to search for within the given input. 要在给定input中搜索的字符串。Can be any valid expression that resolves to a string or a null. 可以是解析为字符串或null的任何有效表达式If find refers to a field that is missing, $replaceAll returns null.如果find引用的字段丢失,$replaceAll返回null

replacement

The string to use to replace all matched instances of find in input. 用于替换inputfind的所有匹配实例的字符串。Can be any valid expression that resolves to a string or a null.可以是解析为字符串或null的任何有效表达式。

Behavior行为

The input, find, and replacement expressions must evaluate to a string or a null, or $replaceAll fails with an error.inputfindreplacement表达式的计算结果必须为字符串或null,否则$replaceAll失败并出现错误。

$replaceAll and Null Values和空值

If input or find refer to a field that is missing, they return null.如果inputfind引用的字段缺失,则返回null

If any one of input, find, or replacement evaluates to a null, the entire $replaceAll expression evaluates to null:如果inputfindreplacement中的任何一个计算结果为null,则整个$replaceAll表达式的计算结果为null

Example示例Result
{ $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

String matching for all $replaceAll expressions is always case-sensitive and diacritic-sensitive. Any collation configured on a collection, db.collection.aggregate(), or index is ignored when performing string comparisons with $replaceAll.

For example, create a sample collection with collation strength 1:例如,创建排序规则强度为1的样本集合:

db.createCollection( "myColl", { 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 three example documents:接下来,插入三个示例文档:

db.myColl.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:

db.myColl.aggregate([
  {
    $addFields:
      {
        resultObject: { $replaceAll: { input: "$name", find: "Cafe", replacement: "CAFE" } }
      }
  }
])

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 which 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.

$replaceAll and Unicode Normalization

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.

For example, the character é can be represented in unicode using either one code point or two:

UnicodeDisplays as显示为Code points代码点
\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.

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:

Example示例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 é.

Example示例

Create an inventory collection with the following documents:

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" },
])

The following example replaces each instance of “blue paint” in the item field with “red paint”:

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" }