In MongoDB, the $pow
aggregation pipeline operator raises a number to the specified exponent and returns the result
$pow
accepts two expressions, supplied in an array. The first one is the number, and the second is the exponent. Both can be any valid expression, as long as they resolve to a number.
Example
Suppose we have a collection called test
with the following documents:
{ "_id" : 1, "data" : 10 } { "_id" : 2, "data" : -3 } { "_id" : 3, "data" : 0 } { "_id" : 4, "data" : null }
We can use the $pow
operator to raise the data
field by a specified exponent:
db.test.aggregate(
[
{ $project: {
_id: 0,
result: { $pow: [ "$data", 3 ] }
}
}
]
)
Result:
{ "result" : 1000 } { "result" : -27 } { "result" : 0 } { "result" : null }
In this case, I used the data
field as the number, and 3
as the exponent. Therefore, each document had its data
field raised by the power of 3.
We can see that null
values return null
.
The result is usually the same type as the input. However, there are exceptions to this rule. Specifically:
- A 32-bit integer will be converted to a 64-bit integer if the result is representable as a 64-bit integer.
- A 32-bit integer will be converted to a double if the result is not representable as a 64-bit integer.
- A 64-bit integer will be converted to double if the result is not representable as a 64-bit integer.
Negative Exponent
You cannot raise zero (0
) to a negative exponent.
Example:
db.test.aggregate(
[
{ $match: { _id: 3 } },
{ $project: {
_id: 0,
result: { $pow: [ "$data", -3 ] }
}
}
]
)
Result:
uncaught exception: Error: command failed: { "ok" : 0, "errmsg" : "$pow cannot take a base of 0 and a negative exponent", "code" : 28764, "codeName" : "Location28764" } : 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
The error explicitly states that “$pow cannot take a base of 0 and a negative exponent“.
However, if we exclude document 3, we no longer get the error:
db.test.aggregate(
[
{ $match: { _id: { $nin: [ 3 ] } } },
{ $project: {
result: { $pow: [ "$data", -3 ] }
}
}
]
)
Result:
{ "_id" : 1, "result" : 0.001 } { "_id" : 2, "result" : -0.037037037037037035 } { "_id" : 4, "result" : null }
NaN Values
If the argument resolves to NaN
, $pow
returns NaN
.
Example:
db.test.aggregate(
[
{ $project: {
_id: 0,
result: { $pow: [ "$data" * 1, 3 ] }
}
}
]
)
Result:
{ "result" : NaN } { "result" : NaN } { "result" : NaN } { "result" : NaN }
Non-Existent Fields
If the $pow
operator is applied against a field that doesn’t exist, null
is returned.
Example:
db.test.aggregate(
[
{ $project: {
_id: 0,
result: { $pow: [ "$beer", 3 ] }
}
}
]
)
Result:
{ "result" : null } { "result" : null } { "result" : null } { "result" : null }
Null Exponent
We’ve already seen that a null
value returns null
. This is also true when providing null
as the exponent.
Example:
db.test.aggregate(
[
{ $project: {
_id: 0,
result: { $pow: [ "$data", null ] }
}
}
]
)
Result:
{ "result" : null } { "result" : null } { "result" : null } { "result" : null }