DATACOUCH-168 - Support and document all reduce functions

Detection whether or not reduce should be activated is now centralized. Triggers are:
  - using the count prefix instead of find in method name
  - setting reduce = true in the View annotation explicitly.

The reduce can thus be returning any kind of value (added an integration example with _stats), which is now properly documented.
This commit is contained in:
Simon Baslé
2015-10-20 17:44:43 +02:00
parent ec129e86a8
commit 58d98c5f28
8 changed files with 71 additions and 18 deletions

View File

@@ -52,4 +52,6 @@ public @interface View {
*/
String viewName() default "";
boolean reduce() default false;
}

View File

@@ -68,13 +68,14 @@ public class ViewBasedCouchbaseQuery implements RepositoryQuery {
protected Object guessViewAndExecute() {
String designDoc = designDocName(method);
String methodName = method.getName();
boolean isReduce = methodName.startsWith("count");
boolean isExplicitReduce = method.hasViewAnnotation() && method.getViewAnnotation().reduce();
boolean isReduce = methodName.startsWith("count") || isExplicitReduce;
String viewName = StringUtils.uncapitalize(methodName.replaceFirst("find|count", ""));
ViewQuery simpleQuery = ViewQuery.from(designDoc, viewName)
.stale(operations.getDefaultConsistency().viewConsistency());
if (isReduce) {
simpleQuery.reduce(isReduce);
simpleQuery.reduce();
return executeReduce(simpleQuery, designDoc, viewName);
} else {
return execute(simpleQuery);
@@ -94,15 +95,14 @@ public class ViewBasedCouchbaseQuery implements RepositoryQuery {
//use a ViewQueryCreator to complete the base query
ViewQueryCreator creator = new ViewQueryCreator(tree, new ParametersParameterAccessor(method.getParameters(), runtimeParams),
baseQuery, operations.getConverter());
ViewQuery query = creator.createQuery();
method.getViewAnnotation(), baseQuery, operations.getConverter());
ViewQueryCreator.DerivedViewQuery result = creator.createQuery();
//detect count prefix in the method name and consider it triggers a reduce
if (tree.isCountProjection() == Boolean.TRUE) {
return executeReduce(query, designDoc, viewName);
if (result.isReduce) {
return executeReduce(result.builtQuery, designDoc, viewName);
} else {
//otherwise just execute the query
return execute(query);
return execute(result.builtQuery);
}
} catch (PropertyReferenceException e) {
/*

View File

@@ -30,6 +30,7 @@ import com.couchbase.client.java.document.json.JsonObject;
import com.couchbase.client.java.view.ViewQuery;
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
import org.springframework.data.couchbase.core.view.View;
import org.springframework.data.domain.Sort;
import org.springframework.data.repository.query.ParameterAccessor;
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
@@ -58,18 +59,21 @@ import org.springframework.data.repository.query.parser.PartTree;
* </ul>
* </p>
* Additionally, {@link PartTree#isLimiting()} will use {@link ViewQuery#limit(int) limit}
* and {@link PartTree#isCountProjection()} will trigger a {@link ViewQuery#reduce() reduce}.
* and either {@link View#reduce()} or {@link PartTree#isCountProjection()} will trigger a {@link ViewQuery#reduce() reduce}.
*/
public class ViewQueryCreator extends AbstractQueryCreator<ViewQuery, ViewQuery> {
public class ViewQueryCreator extends AbstractQueryCreator<ViewQueryCreator.DerivedViewQuery, ViewQuery> {
private ViewQuery query;
private final View viewAnnotation;
private final PartTree tree;
private final int treeCount;
private final CouchbaseConverter converter;
public ViewQueryCreator(PartTree tree, ParameterAccessor parameters, ViewQuery query, CouchbaseConverter converter) {
public ViewQueryCreator(PartTree tree, ParameterAccessor parameters, View viewAnnotation,
ViewQuery query, CouchbaseConverter converter) {
super(tree, parameters);
this.query = query;
this.viewAnnotation = viewAnnotation;
this.tree = tree;
this.converter = converter;
@@ -268,7 +272,7 @@ public class ViewQueryCreator extends AbstractQueryCreator<ViewQuery, ViewQuery>
}
@Override
protected ViewQuery complete(ViewQuery criteria, Sort sort) {
protected DerivedViewQuery complete(ViewQuery criteria, Sort sort) {
boolean descending = false;
if (sort != null) {
@@ -290,8 +294,27 @@ public class ViewQueryCreator extends AbstractQueryCreator<ViewQuery, ViewQuery>
query.limit(tree.getMaxResults());
}
query.reduce(tree.isCountProjection() == Boolean.TRUE);
boolean isCount = tree.isCountProjection() == Boolean.TRUE;
boolean isExplicitReduce = viewAnnotation != null && viewAnnotation.reduce();
if (isCount || isExplicitReduce) {
query.reduce();
}
return query;
return new DerivedViewQuery(query, tree.isLimiting(), isCount || isExplicitReduce);
}
/**
* Wrapper class allowing to see downstream if the built query was built with options like reduce and limit.
*/
protected static class DerivedViewQuery {
public final ViewQuery builtQuery;
public final boolean isLimited;
public final boolean isReduce;
public DerivedViewQuery(ViewQuery builtQuery, boolean isLimited, boolean isReduce) {
this.builtQuery = builtQuery;
this.isLimited = isLimited;
this.isReduce = isReduce;
}
}
}