The $replaceOne
aggregation pipeline operator was introduced in MongoDB 4.4.
This operator replaces the first instance of a search string in an input string with a replacement string and returns the result.
If the search string isn’t found, then $replaceOne
returns the input string.
Example
Suppose we have a collection called products
with the following document:
{ "_id" : 1, "product" : "Left Handed Screwdriver with Left Handed Carry Case" }
Let’s use the $replaceOne
operator to replace the first instance of the string Left Handed
with another string:
db.products.aggregate([
{
$project:
{
product: { $replaceOne: { input: "$product", find: "Left Handed", replacement: "Ambidextrous" } }
}
}
]).pretty()
Result:
{ "_id" : 1, "product" : "Ambidextrous Screwdriver with Left Handed Carry Case" }
Notice that there are actually two instances of the search string (Left Handed
) but only the first instance was replaced.
To replace all instances, use the $replaceAll
operator.
Case Sensitivity
The $replaceOne
operator is case sensitive.
Example:
db.products.aggregate([
{
$project:
{
product: { $replaceOne: { input: "$product", find: "Left handed", replacement: "Ambidextrous" } }
}
}
]).pretty()
Result:
{ "_id" : 1, "product" : "Left Handed Screwdriver with Left Handed Carry Case" }
In this case, I changed the case of a single character in my search string. I changed Handed
to handed
. This resulted in the search string not being found and so nothing was replaced. Therefore, the input string was returned.
Diacritic Sensitivity
The $replaceOne
operator is diacritic sensitive.
Suppose we add the following document to our collection:
{ "_id": 2, "product": "Toupée Tape" }
And now let’s try to search and replace the word Toupée
, but forget to use the acute accent:
db.products.aggregate([
{ $match: { _id: 2 } },
{
$project:
{
product: { $replaceOne: { input: "$product", find: "Toupee", replacement: "Wig" } }
}
}
])
Result:
{ "_id" : 2, "product" : "Toupée Tape" }
No change.
I didn’t include the diacritic in my search string and so there was no match.
Here it is again, but this time I include the diacritic:
db.products.aggregate([
{ $match: { _id: 2 } },
{
$project:
{
product: { $replaceOne: { input: "$product", find: "Toupée", replacement: "Wig" } }
}
}
])
Result:
{ "_id" : 2, "product" : "Wig Tape" }
This time the search string was found and replaced.
Null Expressions
If any of the expressions provided to $replaceOne
are null
, the result is null
.
Here’s an example of providing a null
operator field to $replaceOne
:
db.products.aggregate([
{
$project:
{
product: { $replaceOne: { input: "$product", find: null, replacement: "Ambidextrous" } }
}
}
]).pretty()
Result:
{ "_id" : 1, "product" : null } { "_id" : 2, "product" : null }
In this case the find
operator field was null
and so the result was null
.
Missing Fields
If the input
or find
operator fields refer to a field that doesn’t exist, then the result is null
.
Example:
db.products.aggregate([
{
$project:
{
product: { $replaceOne: { input: "$oops", find: "Left Handed", replacement: "Ambidextrous" } }
}
}
]).pretty()
Result:
{ "_id" : 1, "product" : null } { "_id" : 2, "product" : null }
Non-String Values
All expressions provided to $replaceOne
must evaluate to a string or null
. Providing any other type returns an error.
Suppose we add the following document to our collection:
{ "_id" : 3, "product" : "Long Weight", "price" : NumberDecimal("7.50") }
Let’s try to do a search and replace on the price
field:
db.products.aggregate([
{
$project:
{
product: { $replaceOne: { input: "$price", find: "7.50", replacement: "10.50" } }
}
}
])
Result:
Error: command failed: { "ok" : 0, "errmsg" : "$replaceOne requires that 'input' be a string, found: 7.50", "code" : 51746, "codeName" : "Location51746" } : aggregate failed : _getErrorWithCode@src/mongo/shell/utils.js:25:13 doassert@src/mongo/shell/assert.js:18:14 _assertCommandWorked@src/mongo/shell/assert.js:618:17 assert.commandWorked@src/mongo/shell/assert.js:708:16 DB.prototype._runAggregate@src/mongo/shell/db.js:266:5 DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1046:12 @(shell):1:1
It returns an error, as expected.
Unicode Normalisation
The $replaceOne
operator does not perform any unicode normalisation.
See the MongoDB documentation for more information about this, and an example.