Skip to content

Add support for Scroll API to allow Keyset- and Offset-based scrolling #2787

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 4 commits into from

Conversation

mp911de
Copy link
Member

@mp911de mp911de commented Mar 6, 2023

Tasks:

  • API spike
  • Implementation
  • Review naming
  • Documentation

Closes #2151

@christophstrobl
Copy link
Member

The name of CursorRequest comes with a lot of perception regarding its behaviour based on existing usage of the Cursor term. Keyset pagination itself is also a well established term for what we want to archive, so introducing yet another naming for the very same thing does not seem to be a good idea adding kognitive load for users.
Paging does not necessarily need to return a Page as we've already seen with Slice, Chunk etc., so having something like a Window makes sense.
Maybe we'd be better off by naming it Scrollable and ScrollRequest, while sticking to KeysetPageRequest implementing a ScrollRequest having the method return a Window.


return OffsetCursorRequest.ofSize(getPageSize(), getSort()).withOffset(getOffset());
}

Choose a reason for hiding this comment

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

The created CursorRequest points to page 0 and element offset 0 regardless of the page number. Shouldn't Pageable.getOffset() be passed into ofSize?

* @param sort the cursor result sort order.
* @return a new {@link CursorRequest} with {@link Sort} applied.
*/
CursorRequest withSort(Sort sort);
Copy link
Member

Choose a reason for hiding this comment

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

Why does a request need to know about the sort? I agree that there's value in the ability to change the window size with each request, but changing result order while scrolling through data does not make senes, does it?

Copy link
Member Author

Choose a reason for hiding this comment

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

This was introduced to carry over the final sort from a query method that either defines a sort or accepts a Sort argument.

* @return the {@link CursorRequest} to obtain the next cursor window.
* @throws IllegalStateException if there is no {@link #hasNext() next} cursor window.
*/
CursorRequest nextCursorRequest();
Copy link
Member

Choose a reason for hiding this comment

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

Would it make senes to expose a Position rather than the next request.

@mp911de mp911de changed the title Add support for CursorWindow API to allow Keyset- and Offset-based cursor windowing Add support for Scroll API to allow Keyset- and Offset-based scrolling Mar 9, 2023
* @param direction must not be {@literal null}.
* @return a new {@link KeysetScrollPosition} for the given keyset and {@link Direction}.
*/
public static KeysetScrollPosition of(Map<String, ?> keys, Direction direction) {

Choose a reason for hiding this comment

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

This is impossible to use currently since Direction is declared package private.

* @since 3.1
* @see ScrollPosition
*/
public interface Scroll<T> extends Streamable<T> {
Copy link
Member

@christophstrobl christophstrobl Mar 14, 2023

Choose a reason for hiding this comment

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

I think Window was the better term here. It aligned nicely with ScrollPosition.

}

// obtain the next Scroll
users = repository.findFirst10ByLastnameOrderByFirstname("Doe", users.lastScrollPosition());
Copy link
Member

Choose a reason for hiding this comment

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

When reading this, I had a hard time to find out what the ScrollPosition actually does. Is it including, like give me everything starting (inclusive) at a certain position. Or is it excluding, like return the data and start after the position.
My point here is, should we call it lastScrollPosition or would it better be nextScrollPosition which is also not quite accurate. Does it maybe make sense to have a scroll position that has startAt and startAfter?
Does this read any better ScrollPosition.after(users.lastScrollPosition()) or is it even more confusing?

mp911de and others added 3 commits March 16, 2023 11:54
The intend of WindowIterator is to support users who need to iterate multiple windows. It keeps track of the position and loads the next window if needed so that the user does not have to interact with the position at all.

Also remove the Window methods to get the frist/last position and enforce the index based variant.

Update the documentation to make use of the newly introduced API.
Refactor WindowIterator to return individual objects during scrolling.
christophstrobl pushed a commit that referenced this pull request Mar 16, 2023
See: #2151
Original Pull Request: #2787
christophstrobl added a commit that referenced this pull request Mar 16, 2023
The intend of WindowIterator is to support users who need to iterate multiple windows. It keeps track of the position and loads the next window if needed so that the user does not have to interact with the position at all.

Also remove the Window methods to get the first/last position and enforce the index based variant.

Update the documentation to make use of the newly introduced API.

See: #2151
Original Pull Request: #2787
christophstrobl pushed a commit that referenced this pull request Mar 16, 2023
Refactor WindowIterator to return individual objects during scrolling.

Original Pull Request: #2787
@christophstrobl
Copy link
Member

Merged to main development line.

@mp911de mp911de added this to the 3.1 M3 (2023.0.0) milestone Mar 16, 2023
@mp911de mp911de deleted the issue/2151 branch March 16, 2023 14:53
michael-simons added a commit to spring-projects/spring-data-neo4j that referenced this pull request Mar 17, 2023
Discussed spring-projects/spring-data-commons#2151 and implemented in spring-projects/spring-data-commons#2787 we can build on top and provide basic support for both imperative and reactive repositories.

The support will be available only on the repository level in the first iteration, think

```java
import java.util.UUID;

import org.springframework.data.domain.ScrollPosition;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Window;
import org.springframework.data.neo4j.repository.Neo4jRepository;

public interface ScrollingRepository extends Neo4jRepository<ScrollingEntity, UUID> {
	Window<ScrollingEntity> findTop4By(Sort sort, ScrollPosition position);
}
```

and other derived finder methods that have a limit and a stable sort.

If requested, further support can be added to the templates, too.

Closes #2691.
michael-simons added a commit to spring-projects/spring-data-neo4j that referenced this pull request Mar 20, 2023
Discussed in spring-projects/spring-data-commons#2151 and implemented in spring-projects/spring-data-commons#2787 we can build on top and provide basic support for both imperative and reactive repositories.

The support will be available only on the repository level in the first iteration, think

```java
import java.util.UUID;

import org.springframework.data.domain.ScrollPosition;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Window;
import org.springframework.data.neo4j.repository.Neo4jRepository;

public interface ScrollingRepository extends Neo4jRepository<ScrollingEntity, UUID> {
	Window<ScrollingEntity> findTop4By(Sort sort, ScrollPosition position);
}
```

and other derived finder methods that have a limit and a stable sort.

If requested, further support can be added to the templates, too.

Closes #2691.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for keyset-based scrolling
3 participants