diff --git a/pom.xml b/pom.xml index 08da7a4466..ab7c703223 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2327-SNAPSHOT pom Spring Data MongoDB diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml index bb7d9f03cc..5dedf6b5c8 100644 --- a/spring-data-mongodb-benchmarks/pom.xml +++ b/spring-data-mongodb-benchmarks/pom.xml @@ -7,7 +7,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2327-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml index ae8b9fdb30..2d27f0b4b8 100644 --- a/spring-data-mongodb-distribution/pom.xml +++ b/spring-data-mongodb-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2327-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml index b611cf01a8..015123b5e0 100644 --- a/spring-data-mongodb/pom.xml +++ b/spring-data-mongodb/pom.xml @@ -11,7 +11,7 @@ org.springframework.data spring-data-mongodb-parent - 2.2.0.BUILD-SNAPSHOT + 2.2.0.DATAMONGO-2327-SNAPSHOT ../pom.xml diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslAbstractMongodbQuery.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslAbstractMongodbQuery.java index e9a3ad9e65..6020077aef 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslAbstractMongodbQuery.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/QuerydslAbstractMongodbQuery.java @@ -18,8 +18,13 @@ import java.util.List; import org.bson.Document; +import org.bson.codecs.DocumentCodec; +import org.bson.json.JsonMode; +import org.bson.json.JsonWriterSettings; + import org.springframework.lang.Nullable; +import com.mongodb.MongoClientSettings; import com.querydsl.core.DefaultQueryMetadata; import com.querydsl.core.QueryModifiers; import com.querydsl.core.SimpleQuery; @@ -38,7 +43,7 @@ * 2.0. *

* Modified for usage with {@link MongodbDocumentSerializer}. - * + * * @param concrete subtype * @author laimw * @author Mark Paluch @@ -48,6 +53,9 @@ public abstract class QuerydslAbstractMongodbQuery> implements SimpleQuery { + private static final JsonWriterSettings JSON_WRITER_SETTINGS = JsonWriterSettings.builder().outputMode(JsonMode.SHELL) + .build(); + private final MongodbDocumentSerializer serializer; private final QueryMixin queryMixin; @@ -179,7 +187,7 @@ protected Document createSort(List> orderSpecifiers) { /** * Get the actual {@link QueryMixin} delegate. - * + * * @return */ QueryMixin getQueryMixin() { @@ -195,8 +203,69 @@ Document asDocument() { return createQuery(queryMixin.getMetadata().getWhere()); } + /** + * Returns the {@literal Mongo Shell} representation of the query.
+ * The following query + * + *
+	 *
+	 * where(p.lastname.eq("Matthews")).orderBy(p.firstname.asc()).offset(1).limit(5);
+	 * 
+ * + * results in + * + *
+	 *
+	 * find({"lastname" : "Matthews"}).sort({"firstname" : 1}).skip(1).limit(5)
+	 * 
+ * + * Note that encoding to {@link String} may fail when using data types that cannot be encoded or DBRef's without an + * identifier. + * + * @return never {@literal null}. + */ @Override public String toString() { - return asDocument().toString(); + + Document projection = createProjection(queryMixin.getMetadata().getProjection()); + Document sort = createSort(queryMixin.getMetadata().getOrderBy()); + DocumentCodec codec = new DocumentCodec(MongoClientSettings.getDefaultCodecRegistry()); + + StringBuilder sb = new StringBuilder("find(" + asDocument().toJson(JSON_WRITER_SETTINGS, codec)); + if (!projection.isEmpty()) { + sb.append(", ").append(projection.toJson(JSON_WRITER_SETTINGS, codec)); + } + sb.append(")"); + if (!sort.isEmpty()) { + sb.append(".sort(").append(sort.toJson(JSON_WRITER_SETTINGS, codec)).append(")"); + } + if (queryMixin.getMetadata().getModifiers().getOffset() != null) { + sb.append(".skip(").append(queryMixin.getMetadata().getModifiers().getOffset()).append(")"); + } + if (queryMixin.getMetadata().getModifiers().getLimit() != null) { + sb.append(".limit(").append(queryMixin.getMetadata().getModifiers().getLimit()).append(")"); + } + return sb.toString(); + } + + /** + * Obtain the {@literal Mongo Shell} json query representation. + * + * @return never {@literal null}. + * @since 2.2 + */ + public String toJson() { + return toJson(JSON_WRITER_SETTINGS); + } + + /** + * Obtain the json query representation applying given {@link JsonWriterSettings settings}. + * + * @param settings must not be {@literal null}. + * @return never {@literal null}. + * @since 2.2 + */ + public String toJson(JsonWriterSettings settings) { + return asDocument().toJson(settings); } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/QuerydslRepositorySupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/QuerydslRepositorySupportTests.java index b36084729d..6d908df879 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/QuerydslRepositorySupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/QuerydslRepositorySupportTests.java @@ -39,6 +39,7 @@ import org.springframework.data.mongodb.repository.User; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.util.StringUtils; /** * Unit tests for {@link QuerydslRepositorySupport}. @@ -248,6 +249,39 @@ public void shouldUseStringForValidObjectIdHexStrings() { assertThat(inQuery.fetchOne()).isEqualTo(document); } + @Test // DATAMONGO-2327 + public void toJsonShouldRenderQuery() { + + QPerson p = QPerson.person; + SpringDataMongodbQuery query = repoSupport.from(p).where(p.lastname.eq("Matthews")) + .orderBy(p.firstname.asc()).offset(1).limit(5); + + assertThat(StringUtils.trimAllWhitespace(query.toJson())).isEqualTo("{\"lastname\":\"Matthews\"}"); + } + + @Test // DATAMONGO-2327 + public void toStringShouldRenderQuery() { + + QPerson p = QPerson.person; + User user = new User(); + user.setId("id"); + SpringDataMongodbQuery query = repoSupport.from(p) + .where(p.lastname.eq("Matthews").and(p.coworker.eq(user))); + + assertThat(StringUtils.trimAllWhitespace(query.toString())) + .isEqualTo("find({\"lastname\":\"Matthews\",\"coworker\":{\"$ref\":\"user\",\"$id\":\"id\"}})"); + + query = query.orderBy(p.firstname.asc()); + assertThat(StringUtils.trimAllWhitespace(query.toString())) + .isEqualTo( + "find({\"lastname\":\"Matthews\",\"coworker\":{\"$ref\":\"user\",\"$id\":\"id\"}}).sort({\"firstname\":1})"); + + query = query.offset(1).limit(5); + assertThat(StringUtils.trimAllWhitespace(query.toString())) + .isEqualTo( + "find({\"lastname\":\"Matthews\",\"coworker\":{\"$ref\":\"user\",\"$id\":\"id\"}}).sort({\"firstname\":1}).skip(1).limit(5)"); + } + @Data @Document public static class Outer {