Skip to content

DATAMONGO-1141 - Add support for $push $sort in Update. #405

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

Closed
Closed
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>1.10.0.BUILD-SNAPSHOT</version>
<version>1.10.0.DATAMONGO-1141-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Spring Data MongoDB</name>
Expand Down
4 changes: 2 additions & 2 deletions spring-data-mongodb-cross-store/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.10.0.BUILD-SNAPSHOT</version>
<version>1.10.0.DATAMONGO-1141-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down Expand Up @@ -48,7 +48,7 @@
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.10.0.BUILD-SNAPSHOT</version>
<version>1.10.0.DATAMONGO-1141-SNAPSHOT</version>
</dependency>

<dependency>
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 @@ -13,7 +13,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.10.0.BUILD-SNAPSHOT</version>
<version>1.10.0.DATAMONGO-1141-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion spring-data-mongodb-log4j/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.10.0.BUILD-SNAPSHOT</version>
<version>1.10.0.DATAMONGO-1141-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 @@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb-parent</artifactId>
<version>1.10.0.BUILD-SNAPSHOT</version>
<version>1.10.0.DATAMONGO-1141-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import java.util.Set;

import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

Expand All @@ -44,6 +47,7 @@
* @author Thomas Darimont
* @author Alexey Plotnik
* @author Mark Paluch
* @author Pavel Vodrazka
*/
public class Update {

Expand Down Expand Up @@ -660,6 +664,58 @@ public Object getValue() {
return this.count;
}
}

/**
* Implementation of {@link Modifier} representing {@code $sort}.
*
* @author Pavel Vodrazka
* @since 1.10
*/
private static class SortModifier implements Modifier {

private final Object sort;

public SortModifier(Direction direction) {
this.sort = direction.isAscending() ? 1 : -1;
}

public SortModifier(Sort sort) {
this.sort = createDBObject(sort);
}

private DBObject createDBObject(Sort sort) {

DBObject obj = new BasicDBObject();

for (Order order : sort) {
if (order.isIgnoreCase()) {
throw new IllegalArgumentException(String.format("Given sort contained an Order for %s with ignore case! "
+ "MongoDB does not support sorting ignoring case currently!", order.getProperty()));
}
obj.put(order.getProperty(), order.isAscending() ? 1 : -1);
}

return obj;
}

/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.Update.Modifier#getKey()
*/
@Override
public String getKey() {
return "$sort";
}

/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.query.Update.Modifier#getValue()
*/
@Override
public Object getValue() {
return this.sort;
}
}

/**
* Builder for creating {@code $push} modifiers
Expand Down Expand Up @@ -707,6 +763,36 @@ public PushOperatorBuilder slice(int count) {
return this;
}

/**
* Propagates {@code $sort} to {@code $push}. {@code $sort} requires the {@code $each} operator.
* Forces elements to be sorted by values in given {@literal direction}.
*
* @param direction must not be {@literal null}.
* @return never {@literal null}.
* @since 1.10
*/
public PushOperatorBuilder sort(Direction direction) {

Assert.notNull(direction, "Direction must not be 'null'.");
this.modifiers.addModifier(new SortModifier(direction));
return this;
}

/**
* Propagates {@code $sort} to {@code $push}. {@code $sort} requires the {@code $each} operator.
* Forces document elements to be sorted in given {@literal order}.
*
* @param order must not be {@literal null}.
* @return never {@literal null}.
* @since 1.10
*/
public PushOperatorBuilder sort(Sort order) {

Assert.notNull(order, "Order must not be 'null'.");
this.modifiers.addModifier(new SortModifier(order));
return this;
}

/**
* Forces values to be added at the given {@literal position}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.springframework.data.mongodb.core.convert;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.collection.IsMapContaining.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
Expand All @@ -42,6 +43,9 @@
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.annotation.Id;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.DBObjectTestUtils;
Expand All @@ -68,6 +72,7 @@
* @author Christoph Strobl
* @author Thomas Darimont
* @author Mark Paluch
* @author Pavel Vodrazka
*/
@RunWith(MockitoJUnitRunner.class)
public class UpdateMapperUnitTests {
Expand Down Expand Up @@ -416,6 +421,68 @@ public void updatePushEachWithSliceShouldRenderWhenUsingMultiplePushCorrectly()
assertThat(key2.containsField("$each"), is(true));
}

/**
* @see DATAMONGO-1141
*/
@Test
public void updatePushEachWithValueSortShouldRenderCorrectly() {

Update update = new Update().push("scores").sort(Direction.DESC).each(42, 23, 68);

DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(), context.getPersistentEntity(Object.class));

DBObject push = getAsDBObject(mappedObject, "$push");
DBObject key = getAsDBObject(push, "scores");

assertThat(key.containsField("$sort"), is(true));
assertThat((Integer) key.get("$sort"), is(-1));
assertThat(key.containsField("$each"), is(true));
}

/**
* @see DATAMONGO-1141
*/
@Test
public void updatePushEachWithDocumentSortShouldRenderCorrectly() {

Update update = new Update().push("names").sort(new Sort(new Order(Direction.ASC, "last"), new Order(Direction.ASC, "first")))
.each(Collections.emptyList());

DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(), context.getPersistentEntity(Object.class));

DBObject push = getAsDBObject(mappedObject, "$push");
DBObject key = getAsDBObject(push, "names");

assertThat(key.containsField("$sort"), is(true));
assertThat((DBObject) key.get("$sort"), equalTo(new BasicDBObjectBuilder().add("last", 1).add("first", 1).get()));
assertThat(key.containsField("$each"), is(true));
}

/**
* @see DATAMONGO-1141
*/
@Test
public void updatePushEachWithSortShouldRenderCorrectlyWhenUsingMultiplePush() {

Update update = new Update().push("authors").sort(Direction.ASC).each("Harry")
.push("chapters").sort(new Sort(Direction.ASC, "order")).each(Collections.emptyList());

DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(), context.getPersistentEntity(Object.class));

DBObject push = getAsDBObject(mappedObject, "$push");
DBObject key1 = getAsDBObject(push, "authors");

assertThat(key1.containsField("$sort"), is(true));
assertThat((Integer) key1.get("$sort"), is(1));
assertThat(key1.containsField("$each"), is(true));

DBObject key2 = getAsDBObject(push, "chapters");

assertThat(key2.containsField("$sort"), is(true));
assertThat((DBObject) key2.get("$sort"), equalTo(new BasicDBObjectBuilder().add("order", 1).get()));
assertThat(key2.containsField("$each"), is(true));
}

/**
* @see DATAMONGO-410
*/
Expand Down