Skip to content

DATAMONGO-1563 - Add fluent alternative for MongoOperations. #466

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
wants to merge 5 commits into from

Conversation

christophstrobl
Copy link
Member

We now provide an alternative API for MongoOperations that allows defining operations in a more fluent way. This reduces the number of methods and strips down the interface to a minimum while offering a more readable API.

// find all with filter query and projecting return type
template.query(Person.class)
    .matching(query(where("firstname").is("luke")))
    .as(Jedi.class)
    .all();

// update with filter & upsert 
template.update(Person.class)
    .apply(new Update().set("firstname", "Han"))
    .matching(query(where("id").is("han-solo")))
    .upsert();

// remove all matching
template.remove(Jedi.class)
    .inCollection("star-wars")
    .matching(query(where("name").is("luke")))
    .all();

// aggregate
template.aggregateAndReturn(Jedi.class)
    .inCollection("star-wars")
    .by(newAggregation(project("name")))
    .get();

We now provide an alternative API for MongoOperations that allows defining operations in a more fluent way. This reduces the number of methods and strips down the interface to a minimum while offering a more readable API.

// find all with filter query and projecting return type
template.query(Person.class)
    .matching(query(where("firstname").is("luke")))
    .as(Jedi.class)
    .all();

// update with filter & upsert 
template.update(Person.class)
    .apply(new Update().set("firstname", "Han"))
	.matching(query(where("id").is("han-solo")))
    .upsert();

// remove all matching
template.remove(Jedi.class)
    .inCollection(STAR_WARS)
	.matching(query(where("name").is("luke")))
    .all();

// aggregate
template.aggregateAndReturn(Jedi.class)
    .inCollection("star-wars)
    .by(newAggregation(project("name")))
    .get();
*
* @param <T>
*/
interface AggregateOperationBuilderTerminatingOperations<T> {
Copy link
Member

Choose a reason for hiding this comment

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

How about just AggregationOperations?

Copy link
Member Author

Choose a reason for hiding this comment

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

had some back and forth on the names, generally it turned out that we already have similar named components for quite a few of the ones introduced here. So there'd already be AggregationOperation. I do see the point that for having eg. an instance var AggregateOperationBuilderTerminatingOperations findAllInStarWars; does not read nice compared to AggregationOperation findAllInStarWars;. Bottom line,
I'm really open for better naming as long as we can keep it consistent across the interfaces for this feature.

*
* @return
*/
CloseableIterator<T> stream();
Copy link
Member

Choose a reason for hiding this comment

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

I'm a bit torn on CloseableIterator. Streamable doesn't seem to be the right interface here because we expect an executed statement, which is Iterator. Iterator to Java 8 Stream adoption is sort of cumbersome and I wonder whether there might be an interface from our side that is Closeable and able to return a Stream

Copy link
Member Author

Choose a reason for hiding this comment

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

The main goal here was to provide users with an alternative way of interacting with MongoOperations therefore I'd not surprise them with different return types for pretty much the same operation.

* @return
* @throws IllegalArgumentException if resultType is {@literal null}.
*/
<T1> WithQueryBuilder<T1> as(Class<T1> resultType);
Copy link
Member

Choose a reason for hiding this comment

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

Minor: How about R instead of T1? (R -> Result)

Copy link
Member Author

Choose a reason for hiding this comment

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

👍 , even @param in JavaDoc does not match <T1>.

Javadoc, rename RemoveOperationBuilderTerminatingOperations methods to DeleteResult remove() and List findAndRemove (was: all/allAndReturn). Add missing diamonds where necessary. Use lombok where appropriate.

FindIterable<Document> target = delegate.prepare(cursor);

if (limit.isPresent()) {
Copy link
Member

Choose a reason for hiding this comment

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

Rather return limit.map(it -> target.limit(it)).orElse(target)?

@sdeleuze
Copy link
Contributor

sdeleuze commented Jun 8, 2017

I am very interested in leveraging this API in https://github.com/mixitconf/mixit, let me know when available in master (I can update DATAMONGO-1689 to add Kotlin extensions for this new API).

…ntation.

Get rid of 'Builder' within the fluent API interface names.
Roll back method rename all() -> remove() -> all() in TerminatingRemoveOperation and fix position of collection name override in UpdateOperation which lead to a restructured operation flow.
mp911de pushed a commit that referenced this pull request Jun 13, 2017
We now provide an alternative API for MongoOperations that allows defining operations in a fluent way. FluentMongoOperations reduces the number of methods and strips down the interface to a minimum while offering a more readable API.

// find all with filter query and projecting return type
template.query(Person.class)
    .matching(query(where("firstname").is("luke")))
    .as(Jedi.class)
    .all();

// insert
template.insert(Person.class)
    .inCollection(STAR_WARS)
    .one(luke);

// update with filter & upsert
template.update(Person.class)
    .apply(new Update().set("firstname", "Han"))
    .matching(query(where("id").is("han-solo")))
    .upsert();

// remove all matching
template.remove(Jedi.class)
    .inCollection(STAR_WARS)
    .matching(query(where("name").is("luke")))
    .all();

// aggregate
template.aggregateAndReturn(Jedi.class)
    .inCollection("star-wars)
    .by(newAggregation(project("name")))
    .all();

Original pull request: #466.
mp911de added a commit that referenced this pull request Jun 13, 2017
Rename TerminatingAggregationOperation.get() to TerminatingAggregationOperation.all() to name methods consistently. Extract collection name retrieval to method. Javadoc, formatting, add generics where required/use diamond syntax where applicable.

Original pull request: #466.
@mp911de
Copy link
Member

mp911de commented Jun 13, 2017

That's merged and polished now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants