Skip to content

DATACOUCH-588 - Part 2 of framework changes. Add support for projecti… #1040

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

Merged

Conversation

mikereiche
Copy link
Collaborator

@mikereiche mikereiche commented Jan 7, 2021

…on and distinct.

Support for projection is only for properties of the top-level entity. For
instance, in UserSubmission, only the properties below can be specified in
the projection. Projection support does not provide means of specifying
something like address.street - you can only project (or not project) the
whole address property. However, the address type in your resultType could
have a subset of the properties in Address.

If the corresponding submissions in the resultType
contained only the userId property

public class UserSubmission extends ComparableEntity {
private String id;
private String username;
private List roles;
private Address address;
private List submissions;

Support for Distinct - I have appropriated the MongoDB model for Distinct.
It defines a separate DistinctOperationSupport class (within
ExecutableFindByQuerySupport) which supports the distinct( distinctFields )
api and execution. The DistinctOperationSupport class has only a
distinctFields member, and a 'delegate' member, which is an
ExecutableFindByQuerySupport object. TBH, I don't see the advantage
over simply adding a distinctFields member to ExecutableFindByQuerySupport

Amend #1 - changes as discussed in Pull Request
- clean up test entity types

Amend #2

  • Eliminate DistinctOperationSupport class. In MongoDB, only distinct on a single field is supported, so the returnType from distinct was very different from the returnType of other query operations (all(), one() etc. (but so is count(), and it doesn't need it's own class)). In Couchbase, distinct on any fields in the entity is allowed - so the returned type could be the domainType or resultType. And as(resultType) still allows any resultType to be specified. This makes it unnecessary to have combinations of interfaces such as DistinctWithProjection and DistinctWithQuery.

  • Clean up the interfaces in ExecutableFindByQuery. There are two types of interfaces (a) the TerminatingFindByQuery which has the one(), oneValue() first(), firstValue(), all(), count(), exists() and stream(); and (b) the option interfaces (FindByQueryWithConsistency etc), which are essentially with-er interfaces. The changes are:

  1. make all the with-er interfaces base interfaces instead of chaining them together. (I don't know why there isn't simply one interface with all the with-er methods).
  2. make the ExecutableFindByQuery interface extend the Terminating interface and all the with-er interfaces.

Amend #3

  • Add execution support for collections

Amend #4

  • Add tests for collections. This includes a new CollectionAwareIntegrationTests class which extends a new JavaIntegratationTests class which extends the existing ClusterAwareIntegrationTests.

  • Fixed up several issues collections issues that were uncovered by the tests.

  • Did further cleanup of OperationSupport interfaces.

  • You have read the Spring Data contribution guidelines.

  • There is a ticket in the bug tracker for the project in our JIRA.

  • You use the code formatters provided here and have them applied to your changes. Don’t submit any formatting related changes.

  • You submit test cases (unit or integration tests) that back your changes.

  • You added yourself as author in the headers of the classes you touched. Amend the date range in the Apache license header if needed. For new types, add the license header (copy from another file and set the current year only).

@mikereiche mikereiche requested a review from daschl January 7, 2021 00:16
/**
* @author Michael Reiche
*/
static class DistinctOperationSupport<T> implements TerminatingDistinct<T> {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This DistinctOperationSupport is appropriated from MongoDB. I have a hard time understanding why a new OperationSupport class is better than simply following the pattern of scanConsistency and collections - just adding a distinctFields member to FindByQueryOperationSupport and leveraging it throughout.
The issue is even bigger in the Reactive class, where the all() and one() methods are duplication almost verbatim.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right -- I was wondering something similar .. maybe this is worth discussing with @mp911de before we get this in .. I bet there was a reason and maybe it's specific to mongo or history?

@@ -140,55 +140,36 @@
* @return new instance of {@link FindWithProjection}.
* @throws IllegalArgumentException if resultType is {@literal null}.
*/
<R> FindByQueryWithQuery<R> as(Class<R> resultType);
<R> FindWithProjection<R> as(Class<R> resultType);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the name FindByQueryWithProjection would be more consistent with the other FindByQuery interface names.
Same with FindByQueryWithDistinct vs. FindWithDistinct. MongoDB has only Find, while Couchbase has FindById and FindByQuery.

*
* @param scanConsistency the custom scan consistency to use for this query.
*/
TerminatingDistinct<Object> consistentWith(QueryScanConsistency scanConsistency);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should be named withConsistency(), but the method is already named 'consistentWith()' elsewhere. This is a breaking change but should be fixed at some point, as the method consistentWith() (not yet implemented) should take mutation tokens from a previous mutation operation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we just add another consistentWith overload that takes mutation tokens? Then we don't need to break anything and we just carry it forward?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea.
In a separate branch, I'll add a withConsistency(QueryScanConsistency) and deprecate the consistentWith(QueryScanConsistency). Then in a future major release, remove it, leaving only the appropriate withConsistency(QueryScanConsistency) and consistentWith(mutation tokens).

return new ExecutableFindByQuerySupport<>(template, domainType, ALL_QUERY, QueryScanConsistency.NOT_BOUNDED,
"_default._default");
return new ExecutableFindByQuerySupport<T>(template, domainType, domainType, ALL_QUERY,
QueryScanConsistency.NOT_BOUNDED, null);
Copy link
Collaborator Author

@mikereiche mikereiche Jan 7, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here the 'default' resultType for projection is the domainType. This is convenient, but it eliminates the the possibility of having a null resultType. I'm content to keep it this way.
I was thinking of the issue with Expiry, where always having a non-null expiry made it impossible to handle all of (1) default value; (2) override with annotation; (3) override with fluent method including undoing the default value. I don't think that needs to be handled for resultType, but it falls in the same pattern.
I changed the default collection to be null as that did not require any additional code changes, but changing the default resultType to null would require other changes.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe in the worst case we need to come up with a special "null" type of sorts

}

/**
* Distinct Find support.
*
* @author Christoph Strobl
* @since 2.1
* @author Michael Reiche
*/
interface FindDistinct {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above - FindByQueryWithDistinct would be more consistent than FindDistinct

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so do you suggest we make those changes? I guess since it is additive it won't be breaking anyone?

* {@link }.</dd>
* <dt>{@link }</dt>
* <dd>Using {@link } allows retrieval of the raw driver specific format, which returns eg. {@link }.</dd>
* </dl>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Couchbase implementations for Projection and Distinct are much simpler than the MongoDB implementations. The MongoDB implementations would need to bring in about 5,000 lines of code from QueryMapper and its dependencies.

@Override
public Flux<T> all() {
return Flux.defer(() -> {
String statement = delegate.assembleEntityQuery(false, distinctFields);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The additional 'distinctFields' argument to assembleEntityQuery() is the only difference between DistinctOperationSupport and ReactiveFindByQueryOperationSupport. I don't understand why Mongo decided to create a whole new DistinctOperationSupport class. It seems much more complicated than it needs to be.

@@ -44,7 +44,7 @@
*/
public class Query {

private final List<QueryCriteria> criteria = new ArrayList<>();
private final List<QueryCriteriaDefinition> criteria = new ArrayList<>();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is changed to use the interface instead of the class.

public String toN1qlSelectString(ReactiveCouchbaseTemplate template, Class domainClass, Class returnClass,
boolean isCount, String[] distinctFields) {
StringBasedN1qlQueryParser.N1qlSpelValues n1ql = getN1qlSpelValues(template, domainClass, returnClass, isCount,
distinctFields);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now need the projection class (returnClass) and distinctFields to produce the 'select' string.

@mikereiche mikereiche force-pushed the datacouch_part_2_of_n_framework_projection_distinct branch 2 times, most recently from bcdd0f0 to 66015b2 Compare January 7, 2021 22:10

/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.DistinctWithProjection#as(java.lang.Class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mentions mongo?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops. I searched all the files in my commit and fixed them.


/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.ExecutableFindOperation.DistinctWithQuery#matching(org.springframework.data.mongodb.core.query.Query)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

more mongo mentions - there are more but I won't ping you on all of them in this review

}

/**
* Distinct Find support.
*
* @author Christoph Strobl
* @since 2.1
* @author Michael Reiche
*/
interface FindDistinct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so do you suggest we make those changes? I guess since it is additive it won't be breaking anyone?

*
* @param scanConsistency the custom scan consistency to use for this query.
*/
TerminatingDistinct<Object> consistentWith(QueryScanConsistency scanConsistency);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we just add another consistentWith overload that takes mutation tokens? Then we don't need to break anything and we just carry it forward?

.consistentWith(QueryScanConsistency.REQUEST_PLUS).matching(specialUsers).all();
assertEquals(1, foundUsers.size());

final List<UserJustLastName> foundUsersReactive = reactiveCouchbaseTemplate.findByQuery(User.class)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Midway in review I have a basic question.. so here we have:

reactiveCouchbaseTemplate.findByQuery(User.class).as(UserJustLastName.class)

what is the reason we could not just do

reactiveCouchbaseTemplate.findByQuery(UserJustLastName.class)

I assume there is good reason, but I probably don't understand it fully

Copy link
Collaborator Author

@mikereiche mikereiche Jan 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Because the documents are stored with _class = "somepackage.User" and they would not be selected by the query as it would have WHERE _class = "somepackage.UserJustLastName". This is also the reason that there is no as(otherClass) method for ExecutableFindById - it just selection on id.

if (distinctFields != null) {
String distinctFieldsStr = distinctFields.length == 0 ? projectedFields : getDistinctFields(distinctFields);
if (isCount) {
// only works with one field - MB43475
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we raise an explicit exception to the user if its more than one field?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was my mistake. The syntax for a sequence in n1ql is DISTINCT { prop1, prop2 ... }
I was trying to use SQL syntax of DISTINCT prop1, prop2 ...
I've closed MB43475 and will fix my code.

return new ExecutableFindByQuerySupport<>(template, domainType, ALL_QUERY, QueryScanConsistency.NOT_BOUNDED,
"_default._default");
return new ExecutableFindByQuerySupport<T>(template, domainType, domainType, ALL_QUERY,
QueryScanConsistency.NOT_BOUNDED, null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe in the worst case we need to come up with a special "null" type of sorts

/**
* @author Michael Reiche
*/
static class DistinctOperationSupport<T> implements TerminatingDistinct<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right -- I was wondering something similar .. maybe this is worth discussing with @mp911de before we get this in .. I bet there was a reason and maybe it's specific to mongo or history?

@mikereiche mikereiche force-pushed the datacouch_part_2_of_n_framework_projection_distinct branch 4 times, most recently from cc249c8 to a3f9b27 Compare January 13, 2021 04:55
@@ -46,28 +46,29 @@

}

interface FindByIdWithCollection<T> extends TerminatingFindById<T> {
interface FindByIdWithCollection<T> {

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed as much of the dependencies as possible.
There's no need for every interface to extend TerminatingFindById. It's sufficient for ExecutableFindById to extend it.


/**
* Allows to specify a different collection than the default one configured.
*
* @param collection the collection to use in this scope.
*/
TerminatingFindById<T> inCollection(String collection);
ExecutableFindById<T> inCollection(String collection);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if each with-er returns ExecutableFindById, then there is no need to chain the interfaces.

Assert.hasText(collection, "Collection must not be null nor empty.");
return new ExecutableFindByIdSupport<>(template, domainType, collection, fields);
}

@Override
public FindByIdWithCollection<T> project(String... fields) {
public ExecutableFindById<T> project(String... fields) {
Assert.notEmpty(fields, "Fields must not be null nor empty.");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it strange that FindById does projection by project(fields) instead of as(returnType) like everything else.

*/
default ExecutableFindByQuery<T> matching(QueryCriteriaDefinition criteria) {
return matching(Query.query(criteria));
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mongo provides a matching(Criteria) method.

@@ -62,6 +62,8 @@
public Mono<T> one(final String id) {
return Mono.just(id).flatMap(docId -> {
GetOptions options = getOptions().transcoder(RawJsonTranscoder.INSTANCE);
// Instead of project(fields), I think this should be implemented the same as
// FindByQuery as(resultType), and the list of fields should be the properties of resultType
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the run-time for FindById.project() that I questioned above.

row.removeKey(TemplateUtils.SELECT_CAS);
}
return template.support().decodeEntity(id, row.toString(), cas, returnType);
});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a collection has been specified, execute on the scope, otherwise execute on the cluster.

@mikereiche mikereiche force-pushed the datacouch_part_2_of_n_framework_projection_distinct branch from a3f9b27 to bd7e40e Compare January 13, 2021 06:10

}

interface ExecutableFindByAnalytics<T> extends FindByAnalyticsConsistentWith<T>, FindByAnalyticsWithConsistency<T> {}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deprecate consistentWith(), add withConsistency(). This is done for all interfaces that have consistentWith()

Copy link
Contributor

@daschl daschl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me, the only thing I'm unsure on are the interface extension changes -- please triple check that those are not breaking any users out there...

@mikereiche mikereiche force-pushed the datacouch_part_2_of_n_framework_projection_distinct branch 2 times, most recently from 7fc1de4 to 90fb286 Compare January 14, 2021 03:57
…on and distinct.

Support for projection is only for properties of the top-level entity. For instance, in UserSubmission, only the properties below can be specified in the projection. Projection support does not provide means of specifying something like address.street - you can only project (or not project) the whole address property. However, the address type in your resultType could have a subset of the properties in Address.

If the corresponding submissions in the resultType contained only the userId property

public class UserSubmission extends ComparableEntity {
	private String id;
	private String username;
	private List<String> roles;
	private Address address;
	private List<Submission> submissions;

Support for Distinct - I have appropriated the MongoDB model for Distinct.  It defines a separate DistinctOperationSupport class (within ExecutableFindByQuerySupport) which supports the distinct( distinctFields ) api and execution. The DistinctOperationSupport class has only a distinctFields member, and a 'delegate' member, which is an ExecutableFindByQuerySupport object. TBH, I don't see the advantage over simply adding a distinctFields member to ExecutableFindByQuerySupport

Amend #1 - changes as discussed in Pull Request
         - clean up test entity types

Amend #2
- Eliminate DistinctOperationSupport class. In MongoDB, only distinct on a single field is supported, so the returnType from distinct was very different from the returnType of other query operations (all(), one() etc. (but so is count(), and it doesn't need it's own class)). In Couchbase, distinct on any fields in the entity is allowed - so the returned type could be the domainType or resultType. And as(resultType) still allows any resultType to be specified. This makes it unnecessary to have combinations of interfaces such as DistinctWithProjection and DistinctWithQuery.

- Clean up the interfaces in ExecutableFindByQuery. There are two types of interfaces (a) the TerminatingFindByQuery which has the one(), oneValue() first(), firstValue(), all(), count(), exists() and stream(); and (b) the option interfaces (FindByQueryWithConsistency etc), which are essentially with-er interfaces. The changes are:
1) make all the with-er interfaces base interfaces instead of chaining them together. (I don't know why there isn't simply one interface with all the with-er methods).
2) make the ExecutableFindByQuery interface extend the Terminating interface and all the with-er interfaces.

Amend #3
- Add execution support for collections

Amend #4
- Add tests for collections. This includes a new CollectionAwareIntegrationTests class which extends a new JavaIntegratationTests class which extends the existing ClusterAwareIntegrationTests.
- Fixed up several issues collections issues that were uncovered by the tests.
- Did further cleanup of OperationSupport interfaces.

Amend #5
- Revert changes to interfaces in *Operation
- Sorted interfaces in same order for consistency (because of the chaining of interfaces, fluent methods must be called in order).
@mikereiche mikereiche force-pushed the datacouch_part_2_of_n_framework_projection_distinct branch from 90fb286 to 027ec93 Compare January 14, 2021 18:48
@mikereiche mikereiche merged commit 0e8d5a2 into master Jan 14, 2021
jorgerod pushed a commit to jorgerod/spring-data-couchbase that referenced this pull request Jan 15, 2021
…on and distinct. (spring-projects#1040)

Support for projection is only for properties of the top-level entity. For instance, in UserSubmission, only the properties below can be specified in the projection. Projection support does not provide means of specifying something like address.street - you can only project (or not project) the whole address property. However, the address type in your resultType could have a subset of the properties in Address.

If the corresponding submissions in the resultType contained only the userId property

public class UserSubmission extends ComparableEntity {
	private String id;
	private String username;
	private List<String> roles;
	private Address address;
	private List<Submission> submissions;

Support for Distinct - I have appropriated the MongoDB model for Distinct.  It defines a separate DistinctOperationSupport class (within ExecutableFindByQuerySupport) which supports the distinct( distinctFields ) api and execution. The DistinctOperationSupport class has only a distinctFields member, and a 'delegate' member, which is an ExecutableFindByQuerySupport object. TBH, I don't see the advantage over simply adding a distinctFields member to ExecutableFindByQuerySupport

Amend spring-projects#1 - changes as discussed in Pull Request
         - clean up test entity types

Amend spring-projects#2
- Eliminate DistinctOperationSupport class. In MongoDB, only distinct on a single field is supported, so the returnType from distinct was very different from the returnType of other query operations (all(), one() etc. (but so is count(), and it doesn't need it's own class)). In Couchbase, distinct on any fields in the entity is allowed - so the returned type could be the domainType or resultType. And as(resultType) still allows any resultType to be specified. This makes it unnecessary to have combinations of interfaces such as DistinctWithProjection and DistinctWithQuery.

- Clean up the interfaces in ExecutableFindByQuery. There are two types of interfaces (a) the TerminatingFindByQuery which has the one(), oneValue() first(), firstValue(), all(), count(), exists() and stream(); and (b) the option interfaces (FindByQueryWithConsistency etc), which are essentially with-er interfaces. The changes are:
1) make all the with-er interfaces base interfaces instead of chaining them together. (I don't know why there isn't simply one interface with all the with-er methods).
2) make the ExecutableFindByQuery interface extend the Terminating interface and all the with-er interfaces.

Amend spring-projects#3
- Add execution support for collections

Amend spring-projects#4
- Add tests for collections. This includes a new CollectionAwareIntegrationTests class which extends a new JavaIntegratationTests class which extends the existing ClusterAwareIntegrationTests.
- Fixed up several issues collections issues that were uncovered by the tests.
- Did further cleanup of OperationSupport interfaces.

Amend spring-projects#5
- Revert changes to interfaces in *Operation
- Sorted interfaces in same order for consistency (because of the chaining of interfaces, fluent methods must be called in order).

Co-authored-by: mikereiche <michael.reiche@couchbase.com>
mikereiche added a commit that referenced this pull request Feb 16, 2021
…on and distinct. (#1040)

Support for projection is only for properties of the top-level entity. For instance, in UserSubmission, only the properties below can be specified in the projection. Projection support does not provide means of specifying something like address.street - you can only project (or not project) the whole address property. However, the address type in your resultType could have a subset of the properties in Address.

If the corresponding submissions in the resultType contained only the userId property

public class UserSubmission extends ComparableEntity {
	private String id;
	private String username;
	private List<String> roles;
	private Address address;
	private List<Submission> submissions;

Support for Distinct - I have appropriated the MongoDB model for Distinct.  It defines a separate DistinctOperationSupport class (within ExecutableFindByQuerySupport) which supports the distinct( distinctFields ) api and execution. The DistinctOperationSupport class has only a distinctFields member, and a 'delegate' member, which is an ExecutableFindByQuerySupport object. TBH, I don't see the advantage over simply adding a distinctFields member to ExecutableFindByQuerySupport

Amend #1 - changes as discussed in Pull Request
         - clean up test entity types

Amend #2
- Eliminate DistinctOperationSupport class. In MongoDB, only distinct on a single field is supported, so the returnType from distinct was very different from the returnType of other query operations (all(), one() etc. (but so is count(), and it doesn't need it's own class)). In Couchbase, distinct on any fields in the entity is allowed - so the returned type could be the domainType or resultType. And as(resultType) still allows any resultType to be specified. This makes it unnecessary to have combinations of interfaces such as DistinctWithProjection and DistinctWithQuery.

- Clean up the interfaces in ExecutableFindByQuery. There are two types of interfaces (a) the TerminatingFindByQuery which has the one(), oneValue() first(), firstValue(), all(), count(), exists() and stream(); and (b) the option interfaces (FindByQueryWithConsistency etc), which are essentially with-er interfaces. The changes are:
1) make all the with-er interfaces base interfaces instead of chaining them together. (I don't know why there isn't simply one interface with all the with-er methods).
2) make the ExecutableFindByQuery interface extend the Terminating interface and all the with-er interfaces.

Amend #3
- Add execution support for collections

Amend #4
- Add tests for collections. This includes a new CollectionAwareIntegrationTests class which extends a new JavaIntegratationTests class which extends the existing ClusterAwareIntegrationTests.
- Fixed up several issues collections issues that were uncovered by the tests.
- Did further cleanup of OperationSupport interfaces.

Amend #5
- Revert changes to interfaces in *Operation
- Sorted interfaces in same order for consistency (because of the chaining of interfaces, fluent methods must be called in order).

Co-authored-by: mikereiche <michael.reiche@couchbase.com>
mikereiche added a commit that referenced this pull request Feb 16, 2021
…1080)

* DATACOUCH-588 - Part 2 of framework changes. Add support for projection and distinct. (#1040)

Support for projection is only for properties of the top-level entity. For instance, in UserSubmission, only the properties below can be specified in the projection. Projection support does not provide means of specifying something like address.street - you can only project (or not project) the whole address property. However, the address type in your resultType could have a subset of the properties in Address.

If the corresponding submissions in the resultType contained only the userId property

public class UserSubmission extends ComparableEntity {
	private String id;
	private String username;
	private List<String> roles;
	private Address address;
	private List<Submission> submissions;

Support for Distinct - I have appropriated the MongoDB model for Distinct.  It defines a separate DistinctOperationSupport class (within ExecutableFindByQuerySupport) which supports the distinct( distinctFields ) api and execution. The DistinctOperationSupport class has only a distinctFields member, and a 'delegate' member, which is an ExecutableFindByQuerySupport object. TBH, I don't see the advantage over simply adding a distinctFields member to ExecutableFindByQuerySupport

Amend #1 - changes as discussed in Pull Request
         - clean up test entity types

Amend #2
- Eliminate DistinctOperationSupport class. In MongoDB, only distinct on a single field is supported, so the returnType from distinct was very different from the returnType of other query operations (all(), one() etc. (but so is count(), and it doesn't need it's own class)). In Couchbase, distinct on any fields in the entity is allowed - so the returned type could be the domainType or resultType. And as(resultType) still allows any resultType to be specified. This makes it unnecessary to have combinations of interfaces such as DistinctWithProjection and DistinctWithQuery.

- Clean up the interfaces in ExecutableFindByQuery. There are two types of interfaces (a) the TerminatingFindByQuery which has the one(), oneValue() first(), firstValue(), all(), count(), exists() and stream(); and (b) the option interfaces (FindByQueryWithConsistency etc), which are essentially with-er interfaces. The changes are:
1) make all the with-er interfaces base interfaces instead of chaining them together. (I don't know why there isn't simply one interface with all the with-er methods).
2) make the ExecutableFindByQuery interface extend the Terminating interface and all the with-er interfaces.

Amend #3
- Add execution support for collections

Amend #4
- Add tests for collections. This includes a new CollectionAwareIntegrationTests class which extends a new JavaIntegratationTests class which extends the existing ClusterAwareIntegrationTests.
- Fixed up several issues collections issues that were uncovered by the tests.
- Did further cleanup of OperationSupport interfaces.

Amend #5
- Revert changes to interfaces in *Operation
- Sorted interfaces in same order for consistency (because of the chaining of interfaces, fluent methods must be called in order).

Co-authored-by: mikereiche <michael.reiche@couchbase.com>

* DATACOUCH-588 - after cherry-pick, remove reference to 4.2 method deleteAllById().

Original pull request #1040
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants