org.litote.kmongo.MongoCollections.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kmongo-core Show documentation
Show all versions of kmongo-core Show documentation
KMongo synchronous client core extensions
/*
* Copyright (C) 2016/2020 Litote
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.litote.kmongo
import com.mongodb.MongoCommandException
import com.mongodb.bulk.BulkWriteResult
import com.mongodb.client.AggregateIterable
import com.mongodb.client.DistinctIterable
import com.mongodb.client.FindIterable
import com.mongodb.client.ListIndexesIterable
import com.mongodb.client.MapReduceIterable
import com.mongodb.client.MongoCollection
import com.mongodb.client.MongoIterable
import com.mongodb.client.model.BulkWriteOptions
import com.mongodb.client.model.CountOptions
import com.mongodb.client.model.DeleteOptions
import com.mongodb.client.model.FindOneAndDeleteOptions
import com.mongodb.client.model.FindOneAndReplaceOptions
import com.mongodb.client.model.FindOneAndUpdateOptions
import com.mongodb.client.model.IndexOptions
import com.mongodb.client.model.InsertOneOptions
import com.mongodb.client.model.ReplaceOptions
import com.mongodb.client.model.UpdateOptions
import com.mongodb.client.model.WriteModel
import com.mongodb.client.result.DeleteResult
import com.mongodb.client.result.UpdateResult
import org.bson.BsonDocument
import org.bson.conversions.Bson
import org.litote.kmongo.util.KMongoUtil
import org.litote.kmongo.util.PairProjection
import org.litote.kmongo.util.SingleProjection
import org.litote.kmongo.util.TripleProjection
import org.litote.kmongo.util.UpdateConfiguration
import org.litote.kmongo.util.pairProjectionCodecRegistry
import org.litote.kmongo.util.singleProjectionCodecRegistry
import org.litote.kmongo.util.tripleProjectionCodecRegistry
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty1
/**
* Returns a [MongoCollection] with a KMongo codec.
*/
fun MongoCollection.withKMongo(): MongoCollection =
withCodecRegistry(KMongo.configureRegistry(codecRegistry))
/**
* Create a new MongoCollection instance with a different default class to cast any documents returned from the database into..
*
* @param the default class to cast any documents returned from the database into.
* @return a new MongoCollection instance with the different default class
*/
inline fun MongoCollection<*>.withDocumentClass(): MongoCollection =
withDocumentClass(NewTDocument::class.java)
/**
* Counts the number of documents in the collection according to the given options.
*
* @param filter the query filter
* @param options the options describing the count
*
* @return the number of documents in the collection
*/
fun MongoCollection.countDocuments(filter: String, options: CountOptions = CountOptions()): Long =
countDocuments(KMongoUtil.toBson(filter), options)
/**
* Gets the distinct values of the specified field name.
*
* @param fieldName the field name
* @param filter the query filter
* @param the target type of the iterable.
*
* @return an iterable of distinct values
*/
inline fun MongoCollection<*>.distinct(
fieldName: String,
filter: String = KMongoUtil.EMPTY_JSON
): DistinctIterable = distinct(fieldName, KMongoUtil.toBson(filter), TResult::class.java)
/**
* Gets the distinct values of the specified field.
*
* @param field the field
* @param filter the query filter
* @param the target type of the iterable.
*
* @return an iterable of distinct values
*/
inline fun MongoCollection.distinct(
field: KProperty1,
filter: Bson = EMPTY_BSON
): DistinctIterable = distinct(field.path(), filter, TResult::class.java)
/**
* Finds all documents in the collection.
*
* @param filter the query filter
* @return the find iterable interface
*/
fun MongoCollection.find(filter: String = KMongoUtil.EMPTY_JSON): FindIterable =
find(KMongoUtil.toBson(filter))
/**
* Finds all documents in the collection.
*
* @param filters the query filters
* @return the find iterable interface
*/
fun MongoCollection.find(vararg filters: Bson?): FindIterable = find(and(*filters))
/**
* Finds the first document that match the filter in the collection.
*
* @param filter the query filter
* @return the first item returned or null
*/
fun MongoCollection.findOne(filter: String = KMongoUtil.EMPTY_JSON): T? = find(filter).firstOrNull()
/**
* Finds the first document that match the filter in the collection.
*
* @param filter the query filter
* @return the first item returned or null
*/
fun MongoCollection.findOne(filter: Bson): T? = find(filter).firstOrNull()
/**
* Finds the first document that match the filters in the collection.
*
* @param filters the query filters
* @return the first item returned or null
*/
fun MongoCollection.findOne(vararg filters: Bson?): T? =
find(*filters).firstOrNull()
/**
* Finds the first document that match the filter in the collection.
*
* @param filters the query filters
* @return the first item returned or null
*/
inline fun MongoCollection.findOne(filters: () -> Bson): T? = findOne(filters())
/**
* Finds the document that match the id parameter.
*
* @param id the object id
* @return the first item returned or null
*/
fun MongoCollection.findOneById(id: Any): T? = findOne(KMongoUtil.idFilterQuery(id))
/**
* Aggregates documents according to the specified aggregation pipeline.
*
* @param pipeline the aggregate pipeline
* @param the target document type of the iterable.
*
* @return an iterable containing the result of the aggregation operation
*/
inline fun MongoCollection<*>.aggregate(vararg pipeline: String): AggregateIterable =
aggregate(KMongoUtil.toBsonList(pipeline, codecRegistry), TResult::class.java)
/**
* Aggregates documents according to the specified aggregation pipeline.
*
* @param pipeline the aggregate pipeline
* @param the target document type of the iterable.
*
* @return an iterable containing the result of the aggregation operation
*/
inline fun MongoCollection<*>.aggregate(vararg pipeline: Bson): AggregateIterable =
aggregate(pipeline.toList(), TResult::class.java)
/**
* Aggregates documents according to the specified map-reduce function.
*
* @param mapFunction A JavaScript function that associates or "maps" a value with a key and emits the key and value pair.
* @param reduceFunction A JavaScript function that "reduces" to a single object all the values associated with a particular key.
* @param the target document type of the iterable.
*
* @return an iterable containing the result of the map-reduce operation
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
inline fun MongoCollection<*>.mapReduce(
mapFunction: String,
reduceFunction: String
): MapReduceIterable = mapReduceWith(mapFunction, reduceFunction)
/**
* Aggregates documents according to the specified map-reduce function.
*
* @param mapFunction A JavaScript function that associates or "maps" a value with a key and emits the key and value pair.
* @param reduceFunction A JavaScript function that "reduces" to a single object all the values associated with a particular key.
* @param the target document type of the iterable.
*
* @return an iterable containing the result of the map-reduce operation
*/
inline fun MongoCollection<*>.mapReduceWith(
mapFunction: String,
reduceFunction: String
): MapReduceIterable = mapReduce(mapFunction, reduceFunction, TResult::class.java)
/**
* Inserts the provided document. If the document is missing an identifier, the driver should generate one.
*
* @param document the document to insert
* @param options the options to apply to the operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the insert command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoCommandException if the write failed due to document validation reasons
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
inline fun MongoCollection.insertOne(
document: String,
options: InsertOneOptions = InsertOneOptions()
) = withDocumentClass().insertOne(KMongoUtil.toBson(document, T::class), options)
/**
* Removes at most one document from the collection that matches the given filter. If no documents match, the collection is not
* modified.
*
* @param filter the query filter to apply the the delete operation
*
* @return the result of the remove one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.deleteOne(filter: String): DeleteResult = deleteOne(KMongoUtil.toBson(filter))
/**
* Removes at most one document from the collection that matches the given filter. If no documents match, the collection is not
* modified.
*
* @param filters the query filters to apply the the delete operation
*
* @return the result of the remove one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.deleteOne(vararg filters: Bson?): DeleteResult = deleteOne(and(*filters))
/**
* Removes at most one document from the id parameter. If no documents match, the collection is not
* modified.
*
* @param id the object id
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.deleteOneById(id: Any): DeleteResult = deleteOne(KMongoUtil.idFilterQuery(id))
/**
* Removes all documents from the collection that match the given query filter. If no documents match, the collection is not modified.
*
* @param filter the query filter to apply the the delete operation
* @param options the options to apply to the delete operation
*
* @return the result of the remove many operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.deleteMany(filter: String, options: DeleteOptions = DeleteOptions()): DeleteResult =
deleteMany(KMongoUtil.toBson(filter), options)
/**
* Removes all documents from the collection that match the given query filter. If no documents match, the collection is not modified.
*
* @param filters the query filters to apply the the delete operation
* @param options the options to apply to the delete operation
*
* @return the result of the remove many operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the delete command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.deleteMany(vararg filters: Bson?, options: DeleteOptions = DeleteOptions()): DeleteResult =
deleteMany(and(*filters), options)
/**
* Save the document.
* If the document has no id field, or if the document has a null id value, insert the document.
* Otherwise, call [replaceOneById] with upsert true.
*
* @param document the document to save
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.save(document: T) {
val id = KMongoUtil.getIdValue(document)
if (id != null) {
replaceOneById(id, document, ReplaceOptions().upsert(true))
} else {
insertOne(document)
}
}
/**
* Replace a document in the collection according to the specified arguments.
*
* @param id the object id
* @param replacement the replacement document
* @param options the options to apply to the replace operation
* @return the result of the replace one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.replaceOneById(
id: Any,
replacement: T,
options: ReplaceOptions = ReplaceOptions()
): UpdateResult = withDocumentClass().replaceOne(
KMongoUtil.idFilterQuery(id),
KMongoUtil.filterIdToBson(replacement), options
)
/**
* Replace a document in the collection according to the specified arguments.
*
* @param replacement the document to replace - must have an non null id
* @param options the options to apply to the replace operation
* @return the result of the replace one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
inline fun MongoCollection.replaceOne(
replacement: T,
options: ReplaceOptions = ReplaceOptions()
): UpdateResult = replaceOneById(KMongoUtil.extractId(replacement, T::class), replacement, options)
/**
* Replace a document in the collection according to the specified arguments.
*
* @param filter the query filter to apply to the replace operation
* @param replacement the replacement document
* @param options the options to apply to the replace operation
* @return the result of the replace one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.replaceOne(
filter: String,
replacement: T,
options: ReplaceOptions = ReplaceOptions()
): UpdateResult = withDocumentClass()
.replaceOne(
KMongoUtil.toBson(filter),
KMongoUtil.filterIdToBson(replacement),
options
)
/**
* Replace a document in the collection according to the specified arguments.
* Same than [MongoCollection.replaceOne] but ensure that any _id present
* in [replacement] is removed to avoid MongoWriteException such as:
* "After applying the update, the (immutable) field '_id' was found to have been altered to _id"
*
* Note: Supports retryable writes on MongoDB server versions 3.6 or higher when the retryWrites setting is enabled.
* @param filter the query filter to apply the the replace operation
* @param replacement the replacement document
* @param replaceOptions the options to apply to the replace operation
* @return the result of the replace one operation
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the replace command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
* @since 3.7
*/
fun MongoCollection.replaceOneWithFilter(
filter: Bson,
replacement: T,
replaceOptions: ReplaceOptions = ReplaceOptions()
): UpdateResult = withDocumentClass().replaceOne(
filter,
KMongoUtil.filterIdToBson(replacement), replaceOptions
)
/**
* Update a single document in the collection according to the specified arguments.
*
* @param filter a document describing the query filter
* @param update a document describing the update. The update to apply must include only update operators.
* @param options the options to apply to the update operation
*
* @return the result of the update one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.updateOne(
filter: String,
update: String,
options: UpdateOptions = UpdateOptions()
): UpdateResult = updateOne(KMongoUtil.toBson(filter), KMongoUtil.toBson(update), options)
/**
* Update a single document in the collection according to the specified arguments.
*
* @param filter a document describing the query filter
* @param update the update object
* @param options the options to apply to the update operation
* @param updateOnlyNotNullProperties if true do not change null properties
*
* @return the result of the update one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.updateOne(
filter: String,
update: Any,
options: UpdateOptions = UpdateOptions(),
updateOnlyNotNullProperties: Boolean = UpdateConfiguration.updateOnlyNotNullProperties
): UpdateResult =
updateOne(KMongoUtil.toBson(filter), KMongoUtil.toBsonModifier(update, updateOnlyNotNullProperties), options)
/**
* Update a single document in the collection according to the specified arguments.
*
* @param target the update object - must have an non null id
* @param options the options to apply to the update operation
* @param updateOnlyNotNullProperties if true do not change null properties
*
* @return the result of the update one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
inline fun MongoCollection.updateOne(
target: T,
options: UpdateOptions = UpdateOptions(),
updateOnlyNotNullProperties: Boolean = UpdateConfiguration.updateOnlyNotNullProperties
): UpdateResult = updateOneById(KMongoUtil.extractId(target, T::class), target, options, updateOnlyNotNullProperties)
/**
* Update a single document in the collection according to the specified arguments.
*
* @param filter a document describing the query filter
* @param update the update object
* @param options the options to apply to the update operation
*
* @return the result of the update one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.updateOne(
filter: Bson,
target: Any,
options: UpdateOptions = UpdateOptions(),
updateOnlyNotNullProperties: Boolean = UpdateConfiguration.updateOnlyNotNullProperties
): UpdateResult = updateOne(filter, KMongoUtil.toBsonModifier(target, updateOnlyNotNullProperties), options)
/**
* Update a single document in the collection according to the specified arguments.
*
* @param filter a document describing the query filter
* @param updates the setTo describing the updates
* @param options the options to apply to the update operation
*
* @return the result of the update one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.updateOne(
filter: Bson,
vararg updates: SetTo<*>,
updateOptions: UpdateOptions = UpdateOptions()
): UpdateResult = updateOne(filter, set(*updates), updateOptions)
/**
* Update a single document in the collection according to the specified arguments.
*
* @param id the object id
* @param update the update object
* @param options the options to apply to the update operation
* @param updateOnlyNotNullProperties if true do not change null properties
*
* @return the result of the update one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.updateOneById(
id: Any,
update: Any,
options: UpdateOptions = UpdateOptions(),
updateOnlyNotNullProperties: Boolean = UpdateConfiguration.updateOnlyNotNullProperties
): UpdateResult =
updateOne(KMongoUtil.idFilterQuery(id), KMongoUtil.toBsonModifier(update, updateOnlyNotNullProperties), options)
/**
* Update all documents in the collection according to the specified arguments.
*
* @param filter a document describing the query filter, which may not be null.
* @param update a document describing the update, which may not be null. The update to apply must include only update operators.
* @param updateOptions the options to apply to the update operation
*
* @return the result of the update one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.updateMany(
filter: String,
update: String,
updateOptions: UpdateOptions = UpdateOptions()
): UpdateResult = updateMany(KMongoUtil.toBson(filter), KMongoUtil.toBson(update), updateOptions)
/**
* Update all documents in the collection according to the specified arguments.
*
* @param filter a document describing the query filter, which may not be null.
* @param updates a document describing the update, which may not be null. The update to apply must include only update operators.
* @param updateOptions the options to apply to the update operation
*
* @return the result of the update one operation
*
* @throws com.mongodb.MongoWriteException if the write failed due some other failure specific to the update command
* @throws com.mongodb.MongoWriteConcernException if the write failed due being unable to fulfil the write concern
* @throws com.mongodb.MongoException if the write failed due some other failure
*/
fun MongoCollection.updateMany(
filter: Bson,
vararg updates: SetTo<*>,
updateOptions: UpdateOptions = UpdateOptions()
): UpdateResult = updateMany(filter, set(*updates), updateOptions)
/**
* Atomically find a document and remove it.
*
* @param filter the query filter to find the document with
* @param options the options to apply to the operation
*
* @return the document that was removed. If no documents matched the query filter, then null will be returned
*/
fun MongoCollection.findOneAndDelete(
filter: String,
options: FindOneAndDeleteOptions = FindOneAndDeleteOptions()
): T? = findOneAndDelete(KMongoUtil.toBson(filter), options)
/**
* Atomically find a document and replace it.
*
* @param filter the query filter to apply the the replace operation
* @param replacement the replacement document
* @param options the options to apply to the operation
*
* @return the document that was replaced. Depending on the value of the `returnOriginal` property, this will either be the
* document as it was before the update or as it is after the update. If no documents matched the query filter, then null will be
* returned
*/
fun MongoCollection.findOneAndReplace(
filter: String,
replacement: T,
options: FindOneAndReplaceOptions = FindOneAndReplaceOptions()
): T? = findOneAndReplace(KMongoUtil.toBson(filter), replacement, options)
/**
* Atomically find a document and update it.
*
* @param filter a document describing the query filter, which may not be null.
* @param update a document describing the update, which may not be null. The update to apply must include only update operators.
* @param options the options to apply to the operation
*
* @return the document that was updated. Depending on the value of the `returnOriginal` property, this will either be the
* document as it was before the update or as it is after the update. If no documents matched the query filter, then null will be
* returned
*/
fun MongoCollection.findOneAndUpdate(
filter: String,
update: String,
options: FindOneAndUpdateOptions = FindOneAndUpdateOptions()
): T? = findOneAndUpdate(KMongoUtil.toBson(filter), KMongoUtil.toBson(update), options)
/**
* Create an index with the given keys and options.
*
* @param keys an object describing the index key(s), which may not be null.
* @param indexOptions the options for the index
* @return the index name
*/
fun MongoCollection.createIndex(keys: String, indexOptions: IndexOptions = IndexOptions()): String =
createIndex(KMongoUtil.toBson(keys), indexOptions)
/**
* Create an index with the given keys and options.
* If the creation of the index is not doable because an index with the same keys but with different [IndexOptions]
* already exists, then drop the existing index and create a new one.
*
* @param keys an object describing the index key(s), which may not be null.
* @param indexOptions the options for the index
* @return the index name
*/
fun MongoCollection.ensureIndex(keys: Bson, indexOptions: IndexOptions = IndexOptions()): String {
return try {
createIndex(keys, indexOptions)
} catch (e: MongoCommandException) {
//there is an exception if the parameters of an existing index are changed.
//then drop the index and create a new one
try {
dropIndex(keys)
} catch (e2: Exception) {
//ignore
}
createIndex(keys, indexOptions)
}
}
/**
* Create an ascending index with the given keys and options.
* If the creation of the index is not doable because an index with the same keys but with different [IndexOptions]
* already exists, then drop the existing index and create a new one.
*
* @param keys the properties, which must contain at least one
* @param indexOptions the options for the index
* @return the index name
*/
fun MongoCollection.ensureIndex(
vararg properties: KProperty<*>,
indexOptions: IndexOptions = IndexOptions()
): String = ensureIndex(ascending(*properties), indexOptions)
/**
* Create an [IndexOptions.unique] index with the given keys and options.
* If the creation of the index is not doable because an index with the same keys but with different [IndexOptions]
* already exists, then drop the existing index and create a new one.
*
* @param keys the properties, which must contain at least one
* @param indexOptions the options for the index
* @return the index name
*/
fun MongoCollection.ensureUniqueIndex(
vararg properties: KProperty<*>,
indexOptions: IndexOptions = IndexOptions()
): String = ensureIndex(properties = *properties, indexOptions = indexOptions.unique(true))
/**
* Create an index with the given keys and options.
* If the creation of the index is not doable because an index with the same keys but with different [IndexOptions]
* already exists, then drop the existing index and create a new one.
*
* @param keys an object describing the index key(s), which may not be null.
* @param indexOptions the options for the index
* @return the index name
*/
fun MongoCollection.ensureIndex(keys: String, indexOptions: IndexOptions = IndexOptions()): String {
return try {
createIndex(keys, indexOptions)
} catch (e: MongoCommandException) {
//there is an exception if the parameters of an existing index are changed.
//then drop the index and create a new one
try {
dropIndexOfKeys(keys)
} catch (e2: Exception) {
//ignore
}
createIndex(keys, indexOptions)
}
}
/**
* Get all the indexes in this collection.
*
* @param the target document type of the iterable.
* @return the list indexes iterable interface
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
inline fun MongoCollection<*>.listIndexes(): ListIndexesIterable = listTypedIndexes()
/**
* Get all the indexes in this collection.
*
* @param the target document type of the iterable.
* @return the list indexes iterable interface
*/
inline fun MongoCollection<*>.listTypedIndexes(): ListIndexesIterable =
listIndexes(TResult::class.java)
/**
* Drops the index given the keys used to create it.
*
* @param keys the keys of the index to remove
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
fun MongoCollection.dropIndex(keys: String) = dropIndexOfKeys(keys)
/**
* Drops the index given the keys used to create it.
*
* @param json the keys of the index to remove
*/
fun MongoCollection.dropIndexOfKeys(json: String) = dropIndex(KMongoUtil.toBson(json))
/**
* Executes a mix of inserts, updates, replaces, and deletes.
*
* @param requests the writes to execute
* @param options the options to apply to the bulk write operation
*
* @return the result of the bulk write
*/
inline fun MongoCollection.bulkWrite(
vararg requests: String,
options: BulkWriteOptions = BulkWriteOptions()
): BulkWriteResult =
withDocumentClass().bulkWrite(KMongoUtil.toWriteModel(requests, codecRegistry, T::class), options)
/**
* Executes a mix of inserts, updates, replaces, and deletes.
*
* @param requests the writes to execute
* @param options the options to apply to the bulk write operation
*
* @return the result of the bulk write
*/
inline fun MongoCollection.bulkWrite(
vararg requests: WriteModel,
options: BulkWriteOptions = BulkWriteOptions()
): BulkWriteResult = bulkWrite(requests.toList(), options)
/**
* Returns the specified field for all matching documents.
*
* @param property the property to return
* @param query the optional find query
* @param options the optional [FindIterable] modifiers
* @return a property value iterable
*/
inline fun MongoCollection.projection(
property: KProperty,
query: Bson = EMPTY_BSON,
options: (FindIterable>) -> FindIterable> = { it }
): MongoIterable =
withDocumentClass>()
.withCodecRegistry(singleProjectionCodecRegistry(property.path(), F::class, codecRegistry))
.find(query)
.let { options(it) }
.projection(fields(excludeId(), include(property)))
.map { it.field }
/**
* Returns the specified two fields for all matching documents.
*
* @param property1 the first property to return
* @param property2 the second property to return
* @param query the optional find query
* @param options the optional [FindIterable] modifiers
* @return a pair of property values iterable
*/
inline fun MongoCollection.projection(
property1: KProperty,
property2: KProperty,
query: Bson = EMPTY_BSON,
options: (FindIterable>) -> FindIterable> = { it }
): MongoIterable> =
withDocumentClass>()
.withCodecRegistry(
pairProjectionCodecRegistry(
property1.path(),
F1::class,
property2.path(),
F2::class,
codecRegistry
)
)
.find(query)
.let { options(it) }
.projection(fields(excludeId(), include(property1), include(property2)))
.map { it.field1 to it.field2 }
/**
* Returns the specified three fields for all matching documents.
*
* @param property1 the first property to return
* @param property2 the second property to return
* @param property3 the third property to return
* @param query the optional find query
* @param options the optional [FindIterable] modifiers
* @return a triple of property values iterable
*/
inline fun MongoCollection.projection(
property1: KProperty,
property2: KProperty,
property3: KProperty,
query: Bson = EMPTY_BSON,
options: (FindIterable>) -> FindIterable> = { it }
): MongoIterable> =
withDocumentClass>()
.withCodecRegistry(
tripleProjectionCodecRegistry(
property1.path(),
F1::class,
property2.path(),
F2::class,
property3.path(),
F3::class,
codecRegistry
)
)
.find(query)
.let { options(it) }
.projection(fields(excludeId(), include(property1), include(property2), include(property3)))
.map { Triple(it.field1, it.field2, it.field3) }