Definition
$replaceAll
Replaces all instances of a search string or regex pattern 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: { input: <expression>, find: <expression>, replacement: <expression> } }
Operator Fields
Field | Description |
---|---|
The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a | |
The string to search for within the given input. Can be any valid expression that resolves to a string, a regex, or a | |
The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a |
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.
$replaceAll
and Null Values
If input or find refer to a field that is missing, they return null
.
If any one of input, find, or replacement evaluates to a null
, the entire $replaceAll
expression evaluates to null
:
Example | Result |
---|---|
|
|
|
|
|
|
$replaceAll and Collation
String matching for $replaceAll
expressions is always case-sensitive and diacritic-sensitive. Any collation configured is ignored when performing string comparisons with $replaceAll
.
For example, create a sample collection with collation strength 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.
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:
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
:
{ _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
.
$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:
Unicode Displays 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 é
.
Examples
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" },
] )
Replace Using a String
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" }
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":
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.