Skip to content

Commit

Permalink
feat: add aggregation options
Browse files Browse the repository at this point in the history
  • Loading branch information
jbl428 authored and inflab-int committed Sep 29, 2023
1 parent b5a2721 commit ca91135
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ package com.github.inflab.spring.data.mongodb.core.aggregation
import com.github.inflab.spring.data.mongodb.core.aggregation.search.SearchMetaStageDsl
import com.github.inflab.spring.data.mongodb.core.aggregation.search.SearchStageDsl
import com.github.inflab.spring.data.mongodb.core.annotation.AggregationMarker
import org.bson.Document
import org.springframework.data.mongodb.core.aggregation.Aggregation
import org.springframework.data.mongodb.core.aggregation.AggregationOperation
import org.springframework.data.mongodb.core.aggregation.AggregationOptions
import org.springframework.data.mongodb.core.aggregation.AggregationOptions.DomainTypeMapping
import org.springframework.data.mongodb.core.query.Collation
import kotlin.time.Duration
import kotlin.time.toJavaDuration

/**
* A Kotlin DSL to configure [Aggregation] using idiomatic Kotlin code.
Expand All @@ -15,6 +21,55 @@ import org.springframework.data.mongodb.core.aggregation.AggregationOperation
@AggregationMarker
class AggregationDsl {
private val operations = mutableListOf<AggregationOperation>()
private var options: AggregationOptions? = null

/**
* Configures a set of aggregation options that can be used within an aggregation pipeline.
*
* @param allowDiskUse Override `allowDiskUseByDefault` for a specific query.
* @param explain Specifies to return the information on the processing of the pipeline.
* @param cursor Specify a document that contains options that control the creation of the cursor object.
* @param cursorBatchSize Indicates a cursor with a non-default batch size.
* @param collation Specifies the collation to use for the operation.
* @param comment A user-provided comment to attach to this command.
* @param hint The index to use for the aggregation.
* @param maxTime Specifies a time limit in [Duration].
* @param skipOutput Skip results when running an aggregation.
* Useful in combination with `$merge` or `$out`.
* @param domainTypeMapping Specifies a domain type mappings supported by the mapping layer.
* @see <a href="https://www.mongodb.com/docs/manual/reference/command/aggregate/#command-fields">Aggregation Options</a>
*/
fun options(
allowDiskUse: Boolean? = null,
explain: Boolean? = null,
cursor: Document? = null,
cursorBatchSize: Int? = null,
collation: Collation? = null,
comment: String? = null,
hint: Document? = null,
maxTime: Duration? = null,
skipOutput: Boolean? = null,
domainTypeMapping: DomainTypeMapping? = null,
) {
val builder = AggregationOptions.builder()
allowDiskUse?.let { builder.allowDiskUse(it) }
explain?.let { builder.explain(it) }
cursor?.let { builder.cursor(it) }
cursorBatchSize?.let { builder.cursorBatchSize(it) }
collation?.let { builder.collation(it) }
comment?.let { builder.comment(it) }
hint?.let { builder.hint(it) }
maxTime?.let { builder.maxTime(it.toJavaDuration()) }
if (skipOutput == true) builder.skipOutput()
when (domainTypeMapping) {
DomainTypeMapping.STRICT -> builder.strictMapping()
DomainTypeMapping.RELAXED -> builder.relaxedMapping()
DomainTypeMapping.NONE -> builder.noMapping()
null -> {}
}

options = builder.build()
}

/**
* Passes a document to the next stage that contains a count of the number of documents input to the stage.
Expand Down Expand Up @@ -73,6 +128,9 @@ class AggregationDsl {
*
* @return The [Aggregation] built using the configured operations.
*/
fun build(): Aggregation =
Aggregation.newAggregation(operations)
fun build(): Aggregation {
val aggregation = Aggregation.newAggregation(operations)

return options?.let { aggregation.withOptions(it) } ?: aggregation
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,32 @@ package com.github.inflab.spring.data.mongodb.core.aggregation
import com.github.inflab.spring.data.mongodb.core.aggregation.search.SearchMetaOperation
import com.github.inflab.spring.data.mongodb.core.aggregation.search.SearchOperation
import io.kotest.core.spec.style.FreeSpec
import io.kotest.matchers.booleans.shouldBeFalse
import io.kotest.matchers.booleans.shouldBeTrue
import io.kotest.matchers.shouldBe
import org.bson.Document
import org.springframework.data.mongodb.core.aggregation.Aggregation

internal class AggregationDslTest : FreeSpec({

"option" - {
"should add an options" {
// when
val aggregation = aggregation {
options(
allowDiskUse = true,
explain = true,
)
count("fieldName")
}

// then
aggregation.options.isAllowDiskUse.shouldBeTrue()
aggregation.options.isExplain.shouldBeTrue()
aggregation.options.isSkipResults.shouldBeFalse()
}
}

"count" - {
"should create count stage with field name" {
// when
Expand Down

0 comments on commit ca91135

Please sign in to comment.