filter

abstract fun <V> Field<T, Collection<V>>.filter(id: String): Field<T, V>(source)

Filters an array and performs the specified update only on the filtered items.

Unlike selected, which only updates a single array element, filter can update multiple array elements. filter can also be nested.

Usage

MongoDB doesn't allow specifying the filter within the update itself, it must be specified in the options. The parameter id must match a declared array filter.

You may prefer using the overload which automatically registers the filter.

Example

class User(
val name: String,
val grades: List<Grade>,
)

class Grade(
val subject: String,
val grade: Int,
)

collection.updateOne(
filter = {
User::name eq "Bob"
},
options = {
arrayFilter("maths") {
Grade::subject eq "Maths"
}
},
update = {
User::grades.filter("maths") / Grade::grade inc 10
}
)

This will increment all grades for the subject "Maths" for user "Bob".

External resources


abstract fun <V> Field<T, Collection<V>>.filter(id: String? = null, filter: ArrayFiltersOptionDsl<V>.(it: Field<ArrayFiltersOptionDsl.IteratorType<V>, V>) -> Unit): Field<T, V>(source)

Filters an array and performs the specified update only on the filtered items.

Unlike selected, which only updates a single array element, filter can update multiple array elements. filter can also be nested.

This overload registers the array filter within the option automatically. There is no need to configure opensavvy.ktmongo.dsl.options.WithArrayFilters.arrayFilter.

Example

class User(
val name: String,
val grades: List<Grade>,
)

class Grade(
val subject: String,
val grade: Int,
)

collection.updateOne(
filter = {
User::name eq "Bob"
},
update = {
User::grades.filter {
it / Grade::subject eq "Maths"
} / Grade::grade inc 10
}
)

This will increment all grades for the subject "Maths" for user "Bob".

Operation priority

The operator priority rules in Kotlin mean that the following code:

User::grades / Grade::value.filter { … }

is interpreted as:

User::grades / (Grade::value.filter { … })

which is incorrect.

To avoid this, either use explicit parentheses:

(User::grades / Grade::value).filter { … }

Or use an intermediate variable:

val grades = User::grades / Grade::value
grades.filter { … }

External resources

Parameters

id

The identifier of the generated array filter. If null, a unique identifier is generated automatically.

filter

The filter expression to apply to the array element. The lambda passes a parameter that represents the current item during the iteration. The operators within this lambda are the same as FilterQuery.