Skip to content

ArithmeticValueOperators

Operators to arithmetically combine two or more values.

To learn more about aggregation operators, see AggregationOperators.

Inheritors

Properties

context

@LowLevelApi
abstract override val context: BsonContext

The strategy used when converting from KProperty1 to Field.

field

Converts a Kotlin property into a Field.

Functions

abs

open fun <Context : Any, Result : Number?> abs(value: Value<Context, Result>): Value<Context, Result>

@JvmName(name = "absByField")
open fun <Context : Any, Result : Number?> abs(value: Field<Context, Result>): Value<Context, Result>

@JvmName(name = "absByProperty")
open fun <Context : Any, Result : Number?> abs(value: KProperty1<Context, Result>): Value<Context, Result>

inline fun <Context : Any, Result : Number?> abs(value: Result): Value<Context, Result>

The absolute value of a number.

If the value is null or NaN, it is returned unchanged.

Example

class Sensor(
    val name: String,
    val startTemp: Int,
    val endTemp: Int,
    val diffTemp: Int,
)

collection.updateManyWithPipeline(filter = { Sensor::diffTemp.isNull() }) {
    set {
        Sensor::diffTemp set abs(Sensor::startTemp - Sensor::endTemp)
    }
}

External resources

ceil

open fun <Context : Any, Result : Number?> ceil(value: Value<Context, Result>): Value<Context, Result>

@JvmName(name = "ceilByField")
open fun <Context : Any, Result : Number?> ceil(value: Field<Context, Result>): Value<Context, Result>

@JvmName(name = "ceilByProperty")
open fun <Context : Any, Result : Number?> ceil(value: KProperty1<Context, Result>): Value<Context, Result>

inline fun <Context : Any, Result : Number?> ceil(value: Result): Value<Context, Result>

The smallest integer greater than or equal to the specified value.

If the value is null or NaN, it is returned unchanged.

Example

class Sensor(
    val value: Double,
    val maxBound: Double,
)

collection.aggregate()
    .set {
        Sensor::maxBound set ceil(Sensor::value)
    }.toList()

External resources

div

open infix fun <Context : Any, Result> Value<Context, Result>.div(other: Value<Context, Result>): Value<Context, Result>

@JvmName(name = "divByField")
open infix fun <Context : Any, Result> Value<Context, Result>.div(other: Field<Context, Result>): Value<Context, Result>

infix inline fun <Context : Any, Result> Value<Context, Result>.div(other: Result): Value<Context, Result>

@JvmName(name = "divFieldReceiverByValue")
open infix fun <Context : Any, Result> Field<Context, Result>.div(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "divFieldReceiverByField")
open infix fun <Context : Any, Result> Field<Context, Result>.div(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "divFieldReceiverByResult")
infix inline fun <Context : Any, Result> Field<Context, Result>.div(other: Result): Value<Context, Result>
@JvmName(name = "divResultReceiverByValue")
infix inline fun <Context : Any, Result> Result.div(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "divResultReceiverByField")
infix inline fun <Context : Any, Result> Result.div(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "divResultReceiverByResult")
infix inline fun <Context : Any, Result> Result.div(other: Result): Value<Context, Result>

Divides one aggregation value by another.

Example

class ConferencePlanning(
    val hours: Int,
    val workdays: Double,
)

collection.updateManyWithPipeline {
    set {
        ConferencePlanning::workdays set (of(ConferencePlanning::hours) div of(8))
    }
}

Note: because the / operator is already used in KtMongo for the field accessor (ValueOperators.div), it cannot be used for division. Explicitly spell out div instead. It needs explicit parentheses.

External resources

floor

open fun <Context : Any, Result : Number?> floor(value: Value<Context, Result>): Value<Context, Result>

@JvmName(name = "floorByField")
open fun <Context : Any, Result : Number?> floor(value: Field<Context, Result>): Value<Context, Result>

@JvmName(name = "floorByProperty")
open fun <Context : Any, Result : Number?> floor(value: KProperty1<Context, Result>): Value<Context, Result>

inline fun <Context : Any, Result : Number?> floor(value: Result): Value<Context, Result>

The largest integer less than or equal to the specified value.

If the value is null or NaN, it is returned unchanged.

Example

class Sensor(
    val value: Double,
    val minBound: Double,
)

collection.aggregate()
    .set {
        Sensor::minBound set floor(Sensor::value)
    }.toList()

External resources

get

@JvmName(name = "bsonField")
operator fun <Context : Any, Child> Value<Context, BsonDocument>.get(field: String): Value<Context, Child>

@JvmName(name = "bsonItem")
operator fun <Context : Any, Child> Value<Context, BsonArray>.get(index: Int): Value<Context, Child>

Refers to a child field of a field of type BsonDocument.

Example

class User(
    val _id: ObjectId,
    val name: String,
    val externalData: BsonDocument,
)

users.find {
    User::externalData.get<Profile?>("profile") ne null
}
open operator fun <Context : Any, Result> Value<Context, Collection<Result>>.get(index: Value<Context, Int>): Value<Context, Result>

open operator fun <Context : Any, Result> Value<Context, Collection<Result>>.get(index: Int): Value<Context, Result>

Refers to a specific item in an array, by its index.

Examples

class Pet(
    val name: String,
    val age: Int,
)

class User(
    val pets: List<Pet>,
    val favorite: Pet,
)

users.aggregate()
    .set {
        User::favorite set User::pets[0] / Pet::name
    }

External resources

minus

open operator fun <Context : Any, Result> Value<Context, Result>.minus(other: Value<Context, Result>): Value<Context, Result>

@JvmName(name = "minusByField")
open operator fun <Context : Any, Result> Value<Context, Result>.minus(other: Field<Context, Result>): Value<Context, Result>

@JvmName(name = "minusByProperty")
open operator fun <Context : Any, Result> Value<Context, Result>.minus(other: KProperty1<Context, Result>): Value<Context, Result>

inline operator fun <Context : Any, Result> Value<Context, Result>.minus(other: Result): Value<Context, Result>
@JvmName(name = "minusFieldReceiverByValue")
open operator fun <Context : Any, Result> Field<Context, Result>.minus(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "minusFieldReceiverByField")
open operator fun <Context : Any, Result> Field<Context, Result>.minus(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "minusFieldReceiverByProperty")
open operator fun <Context : Any, Result> Field<Context, Result>.minus(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "minusFieldReceiverByResult")
inline operator fun <Context : Any, Result> Field<Context, Result>.minus(other: Result): Value<Context, Result>
@JvmName(name = "minusPropertyReceiverByValue")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.minus(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "minusPropertyReceiverByField")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.minus(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "minusPropertyReceiverByProperty")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.minus(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "minusPropertyReceiverByResult")
inline operator fun <Context : Any, Result> KProperty1<Context, Result>.minus(other: Result): Value<Context, Result>
@JvmName(name = "minusResultReceiverByValue")
inline operator fun <Context : Any, Result> Result.minus(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "minusResultReceiverByField")
inline operator fun <Context : Any, Result> Result.minus(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "minusResultReceiverByProperty")
inline operator fun <Context : Any, Result> Result.minus(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "minusResultReceiverByResult")
inline operator fun <Context : Any, Result> Result.minus(other: Result): Value<Context, Result>

Subtracts one aggregation value from another.

The second argument is subtracted from the first argument.

Example

class Sale(
    val price: Int,
    val fee: Int,
    val discount: Int,
    val total: Int,
)

collection.updateManyWithPipeline {
    set {
        Sale::total set (Sale::price + Sale::fee - Sale::discount)
    }
}

External resources

of

Refers to a field within an aggregation value.

Example

class Product(
    val acceptanceDate: Instant,
    val publishingDate: Instant,
)

val publishedBeforeAcceptance = products.find {
    expr {
        of(Product::publishingDate) lt of(Product::acceptanceDate)
    }
}
open fun <Result> of(value: Result, type: KType): Value<Any, Result>

inline fun <Result> of(value: Result): Value<Any, Result>

Refers to a Kotlin value within an aggregation value.

Example

class Product(
    val age: Int,
)

val publishedBeforeAcceptance = products.find {
    expr {
        of(Product::age) lt of(15)
    }
}
open fun of(value: BsonType): Value<Any, BsonType>

Refers to a BsonType within an aggregation value.

Example

class Product(
    val age: Int,
)

val publishedBeforeAcceptance = products.find {
    expr {
        of(Product::age).type eq of(BsonType.Int32)
    }
}

plus

open operator fun <Context : Any, Result> Value<Context, Result>.plus(other: Value<Context, Result>): Value<Context, Result>

@JvmName(name = "plusByField")
open operator fun <Context : Any, Result> Value<Context, Result>.plus(other: Field<Context, Result>): Value<Context, Result>

@JvmName(name = "plusByProperty")
open operator fun <Context : Any, Result> Value<Context, Result>.plus(other: KProperty1<Context, Result>): Value<Context, Result>

inline operator fun <Context : Any, Result> Value<Context, Result>.plus(other: Result): Value<Context, Result>
@JvmName(name = "plusFieldReceiverByValue")
open operator fun <Context : Any, Result> Field<Context, Result>.plus(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "plusFieldReceiverByField")
open operator fun <Context : Any, Result> Field<Context, Result>.plus(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "plusFieldReceiverByProperty")
open operator fun <Context : Any, Result> Field<Context, Result>.plus(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "plusFieldReceiverByResult")
inline operator fun <Context : Any, Result> Field<Context, Result>.plus(other: Result): Value<Context, Result>
@JvmName(name = "plusPropertyReceiverByValue")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.plus(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "plusPropertyReceiverByField")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.plus(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "plusPropertyReceiverByProperty")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.plus(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "plusPropertyReceiverByResult")
inline operator fun <Context : Any, Result> KProperty1<Context, Result>.plus(other: Result): Value<Context, Result>
@JvmName(name = "plusResultReceiverByValue")
inline operator fun <Context : Any, Result> Result.plus(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "plusResultReceiverByField")
inline operator fun <Context : Any, Result> Result.plus(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "plusResultReceiverByProperty")
inline operator fun <Context : Any, Result> Result.plus(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "plusResultReceiverByResult")
inline operator fun <Context : Any, Result> Result.plus(other: Result): Value<Context, Result>

Sums two aggregation values.

Example

class Product(
    val name: String,
    val price: Int,
    val dailyPriceIncrease: Int,
)

collection.updateManyWithPipeline {
    set {
        Product::price set (Product::price + Product::dailyPriceIncrease)
    }
}

External resources

times

open operator fun <Context : Any, Result> Value<Context, Result>.times(other: Value<Context, Result>): Value<Context, Result>

@JvmName(name = "timesByField")
open operator fun <Context : Any, Result> Value<Context, Result>.times(other: Field<Context, Result>): Value<Context, Result>

@JvmName(name = "timesByProperty")
open operator fun <Context : Any, Result> Value<Context, Result>.times(other: KProperty1<Context, Result>): Value<Context, Result>

inline operator fun <Context : Any, Result> Value<Context, Result>.times(other: Result): Value<Context, Result>
@JvmName(name = "timesFieldReceiverByValue")
open operator fun <Context : Any, Result> Field<Context, Result>.times(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "timesFieldReceiverByField")
open operator fun <Context : Any, Result> Field<Context, Result>.times(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "timesFieldReceiverByProperty")
open operator fun <Context : Any, Result> Field<Context, Result>.times(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "timesFieldReceiverByResult")
inline operator fun <Context : Any, Result> Field<Context, Result>.times(other: Result): Value<Context, Result>
@JvmName(name = "timesPropertyReceiverByValue")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.times(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "timesPropertyReceiverByField")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.times(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "timesPropertyReceiverByProperty")
open operator fun <Context : Any, Result> KProperty1<Context, Result>.times(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "timesPropertyReceiverByResult")
inline operator fun <Context : Any, Result> KProperty1<Context, Result>.times(other: Result): Value<Context, Result>
@JvmName(name = "timesResultReceiverByValue")
inline operator fun <Context : Any, Result> Result.times(other: Value<Context, Result>): Value<Context, Result>
@JvmName(name = "timesResultReceiverByField")
inline operator fun <Context : Any, Result> Result.times(other: Field<Context, Result>): Value<Context, Result>
@JvmName(name = "timesResultReceiverByProperty")
inline operator fun <Context : Any, Result> Result.times(other: KProperty1<Context, Result>): Value<Context, Result>
@JvmName(name = "timesResultReceiverByResult")
inline operator fun <Context : Any, Result> Result.times(other: Result): Value<Context, Result>

Multiplies two or more aggregation values.

Example

class Sale(
    val price: Double,
    val quantity: Int,
    val total: Double,
)

collection.updateManyWithPipeline {
    set {
        Sale::total set (Sale::price * Sale::quantity)
    }
}

External resources

unsafe

open infix fun <Root, Child> KProperty1<Root, *>.unsafe(child: String): Field<Root, Child>

Refers to a field child of the current field, with no compile-time safety.

open infix fun <Root, Child> KProperty1<Root, *>.unsafe(child: KProperty1<*, Child>): Field<Root, Child>

Refers to a field child of the current field, without checking that it is a field available on the current object.

open infix fun <Root, Child> KProperty1<Root, *>.unsafe(child: Field<*, Child>): Field<Root, Child>

Refers to a field child of the current field, without checking that it is a field available on the current object.

open infix fun <Root, Child> Field<Root, *>.unsafe(child: KProperty1<*, Child>): Field<Root, Child>

Refers to a field child of the current field, without checking that it is a field available on the current object.

open infix fun <Root, Child> Field<Root, *>.unsafe(child: Field<*, Child>): Field<Root, Child>

Refers to a field child of the current field, without checking that it is a field available on the current object.

open infix fun <Root, Type, Child> Field<Root, Type>.unsafe(child: String): Field<Root, Child>

Refers to a field child of the current field, with no compile-time safety.

unsafeCast

Overwrites the represented type of this value.

This method can be useful to bypass type checks.

Example

If a field has changed type over time, the DTO will use the newer type. However, you may still want to write a query using the old type:

class User(
    val _id: ObjectId,
    val name: String,
    val age: Int,
)

users.filter { User::age hasType BsonType.Double }
    .updateManyWithPipeline {
        set {
            User::age set User::age.unsafeCast<Double>() // Reflect the old type
               .toInt() // Convert to the new type
        }
    }