How to use distinct with skip and limit in spring data mongodb - mongodb

I have a requirement where i need to use distinct with skip and limit and i have googled a lot for this but found nothing useful and as per some answers it is not supported with old version spring data mongodb and in the newer version is there any way to use this or is there any solution to achieve distinct with skip and limit with aggregation framework

I have not added distinct but used skip, limit with aggregation
Aggregation agg = newAggregation(match(Criteria.where("goalId").is(goal.getId())), skip((long) request.getPage() * request.getSize()),limit(request.getSize()));
final AggregationResults<ActivityHistory> results = mongoOperations.aggregate(agg, ActivityHistory.class, ActivityHistory.class);
List<ActivityHistory> activityHistoryList = results.getMappedResults();

Related

Is it required to specify Sort for skip limit in Mongodb

I am using skip & limit for mongodb C# driver to fetch tickets batchwise like below,
var data = db.collectionName.Find({}).Skip(1000).Limit(500).ToList()
Data fetching is happening as expected. Need confirmation on whether Sort() is mandatory for Skip & limit methods like below ? or sort will be handled by mongodb if not specified
var data = db.collectionName.Find({}).Sort("{_id:1}").Skip(1000).Limit(500).ToList()
I have removed Sort from query to improve time taken to complete fetch operation.
No, Sort() is not mandatory for Skip() and Limit() methods. You can use them directly like you are using in your query:
var data = db.collectionName.Find({}).Skip(1000).Limit(500).ToList()
To know more about default sort order, refer to below link:
https://stackoverflow.com/questions/11599069/how-does-mongodb-sort-records-when-no-sort-order-is-specified#:~:text=When%20we%20run%20a%20Mongo,objects%20in%20forward%20natural%20order.

Upgrading to Spring Boot Mongodb 2.2.X hides GeoNear Aggregate pipeline results past 100 records

I have a paginated API backed by an Aggregation with a $geoNear pipeline step.
In Mongo versions before 4.2, $geoNear aggregations had a default limit of 100.
To avoid this, it was possible to set the num field to a large number for the NearQuery.
Query query = new Query();
...
NearQuery nearQuery = NearQuery.near(...);
nearQuery.query(query);
//force the geoNear operation to return more than 100 results
nearQuery.num(Integer.MAX_VALUE);
List<AggregationOperation> steps = Lists.newArrayList(geoNear(nearQuery, "distance"));
//add skip and limit operations to mimic pagination functionality
steps.add(skip(pageable.getPageNumber() * pageable.getPageSize()));
steps.add(limit(pageable.getPageSize()));
Aggregation agg = Aggregation.newAggregation(steps);
...
In Mongo version 4.2, the num field has been removed as well as the limit of 100 results (described here in the first note). In response to this, GeoNearOperation.java has been updated in spring-data-mongodb to remove the num field.
Now, I would understand that if I were to connect to a MongoDb server running version 4.2 everything would work as is (disclaimer: I have not tried this.) However, I'm running version 4.0.5 locally and version 3.6.12 in production. Using spring-boot-starter-data-mongodb with version 2.1.13.RELEASE the above code works and paginated results are returned past 100 results. Upgrading to 2.2.0.RELEASE causes the above Aggregation to no longer return past 100 results.
How am I supposed to query a MongoDB database on a version older than 4.2 with the 2.2.X branch of
spring-data-mongodb if the num field is always removed?
yes try using mongoTemplate. It should work
Point point = new Point(51.4678685, -0.0860632);
List<Pub> venues =
mongoTemplate.find(new Query(Criteria.where("location").near(point).maxDistance(0.01)), Pub.class);
further refer
https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#reference

How do I set `skip` (offset) for reactivemongo mongodb driver?

I need to skip a number of documents (offset) from a query, and only return limit number of documents that go after. I know the following naive approach:
collection.find(BSONDocument())
.cursor[T].collect[List](offset+limit).map(_.drop(offset))
but it is not really desired because it will load offset+limit number of documents in JVM memory, whereas I'd like to filter them on the "database" side.
Solution: use QueryOpts. Example:
collection.find(BSONDocument())
.options(QueryOpts(skipN = offset))
.cursor[T].collect[List](limit)
Note that using skip is not very efficient because mongodb does not support effective pagination, it will just skip the desired number by iterating through all the documents.
VasyaNovikov answer is certainly correct. Reactive mongo offers a more intuitive API:
collection.find(BSONDocument())
.skip(offset)
.cursor[T]
.collect[List](limit, Cursor.FailOnError[List[T]]())

Doctrine ODM Distinct With Limit

I have the following problem: I can't limit number of results when using distinct. Exemple :
$stores = $this->dm->createQueryBuilder('Application\Document\Item')
->distinct('storeName')
->limit(10)
->getQuery()
->execute();
This query render 100 entries but I want only 10 results.
With query builder class in ORM you need to use:
->setMaxResults(10);
As per #Siol and #john Smith said, in ODM you could use limit:
->limit(10);
I don't think distinct will work with limit as suggested in the Jira mongodb issue ticket Ability to use Limit() with Distinct():
The current Distinct() implementation only allows for bringing back
ALL distinct values in the collection or matching a query, but there
is no way to limit these results. This would be very convenient and
there are many use cases.

How to retrieve whole document in mongodb distinct query rather than only the key?

Mongodb distinct command returns the list of distinct keys in a given document.
Is there any way to retrieve the whole document rather than only keys using mongodb java driver or morphia?
In the documentation it says:
When possible, the distinct command will use an index to find the documents in the query as well as to return the data.
How does this work, when I try using java driver it always returns the list of keys to my queries. And it doesn't take limit and order queries into consideration. Is it possible to give a order by and limit queries into distinct query?
Thanks for the feedback.