Skip to content

Switch from boolean to String for allowDiskUse flag. #5035

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.x-GH-4667-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data MongoDB</name>
Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-distribution/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.x-GH-4667-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.x-GH-4667-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.springframework.data.mongodb.core.ReadConcernAware;
import org.springframework.data.mongodb.core.ReadPreferenceAware;
import org.springframework.data.mongodb.core.query.Collation;
import org.springframework.data.mongodb.core.query.DiskUse;
import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
Expand Down Expand Up @@ -60,7 +61,7 @@ public class AggregationOptions implements ReadConcernAware, ReadPreferenceAware
private static final String MAX_TIME = "maxTimeMS";
private static final String HINT = "hint";

private final Optional<Boolean> allowDiskUse;
private final DiskUse diskUse;
private final boolean explain;
private final Optional<Document> cursor;
private final Optional<Collation> collation;
Expand All @@ -85,6 +86,15 @@ public AggregationOptions(boolean allowDiskUse, boolean explain, @Nullable Docum
this(allowDiskUse, explain, cursor, null);
}

public AggregationOptions(DiskUse diskUse, boolean explain, @Nullable Document cursor) {
this(diskUse, explain, cursor, null);
}

public AggregationOptions(DiskUse allowDiskUse, boolean explain, @Nullable Document cursor,
@Nullable Collation collation) {
this(allowDiskUse, explain, cursor, collation, null);
}

/**
* Creates a new {@link AggregationOptions}.
*
Expand All @@ -97,7 +107,7 @@ public AggregationOptions(boolean allowDiskUse, boolean explain, @Nullable Docum
*/
public AggregationOptions(boolean allowDiskUse, boolean explain, @Nullable Document cursor,
@Nullable Collation collation) {
this(allowDiskUse, explain, cursor, collation, null, null);
this(DiskUse.of(allowDiskUse), explain, cursor, collation, null, null);
}

/**
Expand All @@ -113,13 +123,18 @@ public AggregationOptions(boolean allowDiskUse, boolean explain, @Nullable Docum
*/
public AggregationOptions(boolean allowDiskUse, boolean explain, @Nullable Document cursor,
@Nullable Collation collation, @Nullable String comment) {
this(allowDiskUse ? DiskUse.ALLOW : DiskUse.DENY, explain, cursor, collation, comment, null);
}

public AggregationOptions(DiskUse allowDiskUse, boolean explain, @Nullable Document cursor,
@Nullable Collation collation, @Nullable String comment) {
this(allowDiskUse, explain, cursor, collation, comment, null);
}

/**
* Creates a new {@link AggregationOptions}.
*
* @param allowDiskUse whether to off-load intensive sort-operations to disk.
* @param diskUse whether to off-load intensive sort-operations to disk.
* @param explain whether to get the execution plan for the aggregation instead of the actual results.
* @param cursor can be {@literal null}, used to pass additional options (such as {@code batchSize}) to the
* aggregation.
Expand All @@ -128,10 +143,10 @@ public AggregationOptions(boolean allowDiskUse, boolean explain, @Nullable Docum
* @param hint can be {@literal null}, used to provide an index that would be forcibly used by query optimizer.
* @since 3.1
*/
private AggregationOptions(@Nullable Boolean allowDiskUse, boolean explain, @Nullable Document cursor,
private AggregationOptions(DiskUse diskUse, boolean explain, @Nullable Document cursor,
@Nullable Collation collation, @Nullable String comment, @Nullable Object hint) {

this.allowDiskUse = Optional.ofNullable(allowDiskUse);
this.diskUse = diskUse;
this.explain = explain;
this.cursor = Optional.ofNullable(cursor);
this.collation = Optional.ofNullable(collation);
Expand Down Expand Up @@ -172,7 +187,7 @@ public static AggregationOptions fromDocument(Document document) {
String comment = document.getString(COMMENT);
Document hint = document.get(HINT, Document.class);

AggregationOptions options = new AggregationOptions(allowDiskUse, explain, cursor, collation, comment, hint);
AggregationOptions options = new AggregationOptions(DiskUse.of(allowDiskUse) , explain, cursor, collation, comment, hint);
if (document.containsKey(MAX_TIME)) {
options.maxTime = Duration.ofMillis(document.getLong(MAX_TIME));
}
Expand All @@ -196,7 +211,7 @@ public static Builder builder() {
* @return {@literal true} if enabled; {@literal false} otherwise (or if not set).
*/
public boolean isAllowDiskUse() {
return allowDiskUse.orElse(false);
return diskUse.equals(DiskUse.ALLOW);
}

/**
Expand All @@ -206,7 +221,7 @@ public boolean isAllowDiskUse() {
* @since 4.2.5
*/
public boolean isAllowDiskUseSet() {
return allowDiskUse.isPresent();
return !diskUse.equals(DiskUse.DEFAULT);
}

/**
Expand Down Expand Up @@ -427,7 +442,7 @@ static Document createCursor(int cursorBatchSize) {
*/
public static class Builder {

private @Nullable Boolean allowDiskUse;
private @Nullable DiskUse diskUse = DiskUse.DEFAULT;
private boolean explain;
private @Nullable Document cursor;
private @Nullable Collation collation;
Expand All @@ -447,8 +462,19 @@ public static class Builder {
*/
@Contract("_ -> this")
public Builder allowDiskUse(boolean allowDiskUse) {
return diskUse(DiskUse.of(allowDiskUse));
}

/**
* Defines whether to off-load intensive sort-operations to disk.
*
* @param diskUse use {@literal true} to allow disk use during the aggregation.
* @return this.
*/
@Contract("_ -> this")
public Builder diskUse(DiskUse diskUse) {

this.allowDiskUse = allowDiskUse;
this.diskUse = diskUse;
return this;
}

Expand Down Expand Up @@ -655,7 +681,7 @@ public Builder noMapping() {
@Contract("-> new")
public AggregationOptions build() {

AggregationOptions options = new AggregationOptions(allowDiskUse, explain, cursor, collation, comment, hint);
AggregationOptions options = new AggregationOptions(diskUse, explain, cursor, collation, comment, hint);
if (maxTime != null) {
options.maxTime = maxTime;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2025-present the original author or authors.
*
* 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
*
* https://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.springframework.data.mongodb.core.query;

import org.jspecify.annotations.Nullable;
import org.springframework.util.StringUtils;

/**
* @author Christoph Strobl
*/
public enum DiskUse {

DEFAULT, ALLOW, DENY;

public static DiskUse of(@Nullable Boolean value) {
return value != null ? (value ? ALLOW : DENY) : DEFAULT;
}

public static DiskUse of(String value) {
if (!StringUtils.hasText(value)) {
return DEFAULT;
}
if (value.toLowerCase().equalsIgnoreCase("true")) {
return ALLOW;
}
return valueOf(value.toUpperCase());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private enum MetaKey {
private Map<String, Object> values = Collections.emptyMap();
private Set<CursorOption> flags = Collections.emptySet();
private @Nullable Integer cursorBatchSize;
private @Nullable Boolean allowDiskUse;
private DiskUse diskUse = DiskUse.DEFAULT;

public Meta() {}

Expand All @@ -66,7 +66,7 @@ public Meta() {}
this.values = new LinkedHashMap<>(source.values);
this.flags = new LinkedHashSet<>(source.flags);
this.cursorBatchSize = source.cursorBatchSize;
this.allowDiskUse = source.allowDiskUse;
this.diskUse = source.diskUse;
}

/**
Expand Down Expand Up @@ -230,7 +230,7 @@ public Set<CursorOption> getFlags() {
*/
@Nullable
public Boolean getAllowDiskUse() {
return allowDiskUse;
return diskUse.equals(DiskUse.DEFAULT) ? null : diskUse.equals(DiskUse.ALLOW);
}

/**
Expand All @@ -244,14 +244,18 @@ public Boolean getAllowDiskUse() {
* @since 3.0
*/
public void setAllowDiskUse(@Nullable Boolean allowDiskUse) {
this.allowDiskUse = allowDiskUse;
setDiskUse(DiskUse.of(allowDiskUse));
}

public void setDiskUse(DiskUse diskUse) {
this.diskUse = diskUse;
}

/**
* @return
*/
public boolean hasValues() {
return !this.values.isEmpty() || !this.flags.isEmpty() || this.cursorBatchSize != null || this.allowDiskUse != null;
return !this.values.isEmpty() || !this.flags.isEmpty() || this.cursorBatchSize != null || !this.diskUse.equals(DiskUse.DEFAULT);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -582,8 +582,13 @@ public Query comment(String comment) {
*/
@Contract("_ -> this")
public Query allowDiskUse(boolean allowDiskUse) {
return diskUse(DiskUse.of(allowDiskUse));
}

@Contract("_ -> this")
public Query diskUse(DiskUse diskUse) {

meta.setAllowDiskUse(allowDiskUse);
meta.setDiskUse(diskUse);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,6 @@
* @since 3.0
* @see Aggregation
*/
boolean allowDiskUse() default false;
String allowDiskUse() default "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.springframework.data.mongodb.core.annotation.Collation;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.query.DiskUse;
import org.springframework.data.mongodb.core.query.UpdateDefinition;
import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.Hint;
Expand Down Expand Up @@ -272,8 +273,9 @@ public org.springframework.data.mongodb.core.query.Meta getQueryMetaAttributes()
}
}

if (meta.allowDiskUse()) {
metaAttributes.setAllowDiskUse(meta.allowDiskUse());
DiskUse diskUse = DiskUse.of(meta.allowDiskUse());
if (!diskUse.equals(DiskUse.DEFAULT)) {
metaAttributes.setAllowDiskUse(diskUse.equals(DiskUse.ALLOW));
}

return metaAttributes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ private Class<?> targetTypeOf(AggregationInvocation invocation) {

private interface SampleRepository extends Repository<Person, Long> {

@Meta(cursorBatchSize = 42, comment = "expensive-aggregation", allowDiskUse = true, maxExecutionTimeMs = 100)
@Meta(cursorBatchSize = 42, comment = "expensive-aggregation", allowDiskUse = "true", maxExecutionTimeMs = 100)
@Aggregation({ RAW_GROUP_BY_LASTNAME_STRING, RAW_SORT_STRING })
PersonAggregate plainStringAggregation();

Expand Down