文档菜单
文档首页
/
MongoDB 手册
/ / /

$replaceOne (聚合查询)

本页内容

  • 定义
  • 语法
  • 行为
  • 示例
$replaceOne

将输入字符串中搜索字符串的第一个实例替换为替换字符串。

如果没有找到任何实例,$replaceOne 等于输入字符串。

$replaceOne 同时区分大小写和变音符号,并且忽略集合上存在的任何排序。

$replaceOne 操作符有以下操作符表达式语法:

{ $replaceOne: { input: <expression>, find: <expression>, replacement: <expression> } }
字段
描述

希望应用 find 的字符串。可以是任何有效的 表达式,该表达式解析为字符串或 null。如果 input 指的是一个缺失的字段,则 $replaceOne 返回 null

在给定的 input 中要搜索的字符串。可以是任何有效的 表达式,该表达式解析为字符串或 null。如果 find 指的是一个缺失的字段,则 $replaceOne 返回 null

用于替换 findinput 中第一个匹配实例的字符串。可以是任何有效的 表达式,该表达式解析为字符串或 null

如果在 input 中未找到 find 的任何实例,则 $replaceOne 的评估结果为输入字符串。

必须评估 inputfindreplacement 表达式,以字符串或 null 的形式,否则 $replaceOne 将因错误而失败。

如果 inputfind 指向一个缺失的字段,它们将返回 null

如果 任何一个 inputfindreplacement 评估为 null,整个 $replaceOne 表达式评估为 null

示例
结果
{ $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 表达式,字符串匹配总是区分大小写和变音符号。当使用 $replaceOne 进行字符串比较时,忽略配置的任何 排序规则

例如,创建一个具有排序规则强度 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é" }
])

以下 $replaceOne 操作尝试在 name 字段中查找并替换 "Cafe" 的第一个实例

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

因为 $replaceOne 忽略了此集合配置的排序规则,所以该操作仅匹配文档 2 中的 "Cafe" 实例

{ "_id" : 1, "name" : "cafe", "resultObject" : "cafe" }
{ "_id" : 2, "name" : "Cafe", "resultObject" : "CAFE" }
{ "_id" : 3, "name" : "café", "resultObject" : "café" }

尊重排序规则的运算符,如 $match,由于此集合的排序规则强度为 1,因此在执行针对 "Cafe" 的字符串比较时将匹配所有三个文档。

$replaceOne 聚合表达式不执行任何 Unicode 正规化。这意味着所有 $replaceOne 表达式的字符串匹配都将考虑在 Unicode 中表示字符时使用的代码点数,以尝试匹配。

例如,字符 é 可以使用一个或两个代码点在 Unicode 中表示

Unicode
显示为
代码点
\xe9
é
1 ( \xe9 )
e\u0301
é
2 ( e + \u0301 )

使用带有 $replaceOnefind 字符串,其中字符 é 在 Unicode 中用一个代码点表示,将不会匹配任何使用两个代码点在 input 字符串中表示的 é 实例。

以下表格显示了当将 "café" 与 input 字符串进行比较时,是否发生匹配,其中 é 用一个或两个代码点表示。此示例中的 find 字符串使用一个代码点表示 é 字符

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

因为 $replaceOne 不执行任何 Unicode 规范化,只有第一次字符串比较匹配,其中 findinput 字符串都使用一个码点来表示 é

创建一个具有以下文档的 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" },
])

以下示例将 item 字段中 "blue paint" 的第一个实例替换为 "red paint"

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

注意,在第 3 个文档中,仅替换了 "blue paint" 的第一个匹配实例。

返回

$regexMatch