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:
@@ -52,4 +52,6 @@ public @interface View {
|
||||
*/
|
||||
String viewName() default "";
|
||||
|
||||
boolean reduce() default false;
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user