<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 08:57:30 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[JAVA-2547] Provide generic api for cursor based paging</title>
                <link>https://jira.mongodb.org/browse/JAVA-2547</link>
                <project id="10006" key="JAVA">Java Driver</project>
                    <description>&lt;p&gt;For large amounts of documents it is not performant to use page-based paging with skip and limit.&lt;br/&gt;
Then it is better to use cursor based paging.That means you query by any attribute sorted and remember the value of the sorted field of the last document you found and give it to the client.&lt;br/&gt;
If the user in the client clicks on &quot;next&quot;, you send the last value to the backend and query with a $gt-operator.&lt;/p&gt;

&lt;p&gt;Here is an article which explains the idea in detail:&lt;br/&gt;
&lt;a href=&quot;https://www.sitepoint.com/paginating-real-time-data-cursor-based-pagination/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://www.sitepoint.com/paginating-real-time-data-cursor-based-pagination/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The problem is, that you have to implement a lot to support that.Inside the java api it could be implemented much easier.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;api-suggestion:&lt;/b&gt;&lt;br/&gt;
MongoCursor&amp;lt;DocumentWithPagingInfo&amp;gt; cursor = collection.findPagable()&lt;/p&gt;

&lt;p&gt;The Class DocumentWithPagingInfo has two methods:&lt;br/&gt;
getDocument() and getPagingKey()&lt;br/&gt;
The pagingKey is a string, which encodes the informations about the used filter and sorting and the actual values of the filtered values.&lt;/p&gt;

&lt;p&gt;This string can be given to the client. And if it passed it to the server application, the server application would call a new method collection.findWithPagingKey(String pagingKey)&lt;/p&gt;

&lt;p&gt;Perhaps the api could be done better.&lt;/p&gt;

&lt;p&gt;You also might ask, why that could not be implemented outside of the framework:&lt;br/&gt;
The pagingcursor must encapsule the filter sort and the actual values. These informations are all known inside the api. Outside it is not possible to implement a generic solution, because outside you cannot get these informations from a query-Object (it is a builder pattern).&lt;/p&gt;
</description>
                <environment></environment>
        <key id="399863">JAVA-2547</key>
            <summary>Provide generic api for cursor based paging</summary>
                <type id="2" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14711&amp;avatarType=issuetype">New Feature</type>
                                            <priority id="4" iconUrl="https://jira.mongodb.org/images/icons/priorities/minor.svg">Minor - P4</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="2">Won&apos;t Fix</resolution>
                                        <assignee username="-1">Unassigned</assignee>
                                    <reporter username="christian.finckler@otto.de">Christian Finckler</reporter>
                        <labels>
                    </labels>
                <created>Sat, 1 Jul 2017 10:56:55 +0000</created>
                <updated>Thu, 6 Apr 2023 18:58:01 +0000</updated>
                            <resolved>Wed, 8 Nov 2017 14:15:27 +0000</resolved>
                                    <version>3.4.2</version>
                                                    <component>API</component>
                                        <votes>0</votes>
                                    <watches>2</watches>
                                                                                                                <comments>
                            <comment id="1614095" author="ross@10gen.com" created="Wed, 5 Jul 2017 14:46:04 +0000"  >&lt;p&gt;Hi &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=chris123&quot; class=&quot;user-hover&quot; rel=&quot;chris123&quot;&gt;chris123&lt;/a&gt;,&lt;/p&gt;

&lt;p&gt;Thanks for your suggestion, while I agree a generic pagination class can make sense for certain users, I think it would be best suited at a higher level than the Java Driver.  There are a couple of reasons for this, firstly, as a drivers team we are unifying the API across driver implementations.  So if this were to be implemented it would have to be specified and implemented across all the drivers.  Secondly, pagination of results, are often only done when displaying results as part of some web interface. For many users of the driver it wouldn&apos;t really make sense. &lt;/p&gt;

&lt;p&gt;As you&apos;ve mentioned there are patterns that can be used to implement pagination successfully. When used correctly, they rely on looking up an indexed value and knowing the last value seen so to issue a &lt;tt&gt;$gt&lt;/tt&gt; query.  This already can be achieved using the &lt;tt&gt;Filters&lt;/tt&gt; helpers in the Java driver, when wanting to paginate the results and use the &lt;tt&gt;Filters.and(originalFilter, Filters.gt(&apos;fieldName&apos;, fieldValue))&lt;/tt&gt;.  You will just need to be able to recreate the originalFilter on each request and extend that value, to create the actual query. To get the json value of the &lt;tt&gt;originalFilter&lt;/tt&gt; if you convert it to a &lt;tt&gt;BasicDBObject&lt;/tt&gt;, &lt;tt&gt;Document&lt;/tt&gt; or &lt;tt&gt;BsonDocument&lt;/tt&gt; you can use the &lt;tt&gt;#toJson&lt;/tt&gt; method.&lt;/p&gt;

&lt;p&gt;While a common pattern for web applications, a generic API as described should be easily achievable if built on-top of the library and work according to your needs.  However, there are many different UX pagination patterns in use! From the previous and next style described above, to numbered lists with ranges of values and so on.  I don&apos;t think you can effectively model a single efficient generic pagination API covering all pagination scenarios.  For those reasons I think any pagination API is best being written at a higher level than the driver.&lt;/p&gt;

&lt;p&gt;I hope that makes sense,&lt;/p&gt;

&lt;p&gt;Ross&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|ht24pz:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>