Database Manual / Reference / Query Language / Expressions

$replaceOne (aggregation)(聚合)

Definition定义

$replaceOne

Replaces the first instance of a search string or regex pattern in an input string with a replacement string.用替换字符串替换输入字符串中搜索字符串或正则表达式模式的第一个实例。

If no occurrences are found, $replaceOne evaluates to the input string.如果没有找到匹配项,$replaceOne将计算为输入字符串。

$replaceOne is both case-sensitive and diacritic-sensitive, and ignores any collation present on a collection.区分大小写和变音符号,并忽略集合上存在的任何排序规则。

Syntax语法

The $replaceOne operator has the following operator expression syntax:$replaceOne运算符具有以下运算符表达式语法

{ $replaceOne: { 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, $replaceOne returns null.如果input引用了缺失的字段,$replaceOne将返回null

find

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

replacement

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

Behavior行为

If no occurrences of find are found in input, $replaceOne evaluates to the input string.如果在input中没有找到find,则$replaceOne的计算结果为input字符串。

The input, find, and replacement expressions must evaluate to one of the following output types:inputfindreplacement表达式的计算结果必须为以下输出类型之一:

  • A string字符串
  • null
  • A regex for find operationsfind操作的正则表达式

Otherwise, $replaceOne fails with an error.否则,$replaceOne将失败并出现错误。

$replaceOne and Null Valuesnull

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 $replaceOne expression evaluates to null:如果inputfindreplacement中的任何一个计算结果为null,则整个$replaceOne表达式计算结果为空:

Example示例Result结果
{ $replaceOne: { input: null, find: "abc", replacement: "ABC" } }null
{ $replaceOne: { input: "abc", find: null, replacement: "ABC" } }null
{ $replaceOne: { input: "abc", find: "abc", replacement: null } }null

$replaceOne and Collation$replaceOne和排序规则

String matching for $replaceOne expressions is always case-sensitive and diacritic-sensitive. $replaceOne表达式的字符串匹配始终区分大小写和变音符号。Any collation configured is ignored when performing string comparisons with $replaceOne.使用$replaceOne执行字符串比较时,将忽略配置的任何排序规则

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 $replaceOne operation tries to find and replace the first instance of "Cafe" in the name field:以下$replaceOne操作尝试查找并替换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 $replaceOne ignores the collation configured for this collection, the operation only matches the instance of "Cafe" in document 2.由于$replaceOne忽略了为此集合配置的排序规则,因此该操作仅匹配文档2中的“Cafe”实例。

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”进行字符串比较时将匹配所有三个文档。

$replaceOne and Unicode NormalizationUnicode标准化

The $replaceOne aggregation expression does not perform any unicode normalization. This means that string matching for all $replaceOne expressions will consider the number of code points used to represent a character in unicode when attempting a match.$replaceOne聚合表达式不执行任何unicode规范化。这意味着,在尝试匹配时,所有$replaceOne表达式的字符串匹配都将考虑用于以unicode表示字符的码点数。

For example, the character é can be represented in unicode using either one code point or two:例如,字符é可以用一个或两个码位以unicode表示:

UnicodeDisplays as显示为Code points码位
\xe9é1 ( \xe9 )
e\u0301é2 ( e + \u0301 )

Using $replaceOne 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.$replaceOnefind字符串一起使用,其中字符é以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. 下表显示了与input字符串相比,find字符串“café”是否匹配,其中é由一个或两个代码点表示。The find string in this example uses one code point to represent the é character:本例中的find字符串使用一个代码点来表示é字符:

Example示例Match匹配
{ $replaceOne: { input: "caf\xe9", find: "café", replacement: "CAFE" } }yes
{ $replaceOne: { input: "cafe\u0301", find: "café", replacement: "CAFE" } }no

Because $replaceOne 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 é.因为$replaceOne不执行任何unicode规范化,所以只有第一个字符串比较匹配,其中findinput字符串都使用一个代码点来表示é

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 the first instance of "blue paint" in the item field with "red paint":以下示例将item字段中的“蓝色油漆”的第一个实例替换为“红色油漆”:

db.inventory.aggregate([
{
$project:
{
item: { $replaceOne: { 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 blue paintbrush" }
{ _id: 4, item: "red paint with green paintbrush" }

Note that with document 3, only the first matched instance of "blue paint" is replaced.请注意,在文档3中,只有第一个匹配的“蓝色油漆”实例被替换。

Replace Using Regex使用正则表达式替换

The following example replaces the first instance of "blue" as a whole word in the item field with "navy":以下示例将item字段中“blue”作为一个完整单词的第一个实例替换为“navy”:

db.inventory.aggregate([
{
$project:
{
item: { $replaceOne: { input: "$item", find: \\bblue\\b, replacement: "navy" } }
}
}
]);

The operation returns the following results:该操作返回以下结果:

{ _id: 1, item: "navy paint" }
{ _id: 2, item: "navy and green paint" }
{ _id: 3, item: "navy paint with blue paintbrush" }
{ _id: 4, item: "navy paint with green paintbrush" }

Note that with document 3, only the first matched instance of "blue" is replaced.请注意,在文档3中,只有第一个匹配的“蓝色”实例被替换。