I have a mongo collection which stores orders for a shopping site. Therefore, it starts from 0 and goes up 1 by 1. I want to search for documents, 10 each time, but starting from the max order number all the way down to 0.
In order to do this, I had the idea of getting the max order number and then simply query for the order number from max-10 to max.
Is there a better way to do this? And also, how do I get the maximum order number?
You can use aggregation query to achieve this
var limit = 10;
var offset = page_no > 1 ? (page_no-1) * limit : 0;
Orders.aggregate([
{
$sort:{
'order_no':-1
}
},{
$skip:offset
},{
$limit:limit
}
])
Here order_no is the Number type in your schema as you mentioned & offset will be set based on the page_no you increase from 1-N
Related
Azure Search returns a maximum of 1,000 results at a time. For paging on the client, I want the total count of matches in order to be able to display the correct number of paging buttons at the bottom and in order to be able to tell the user how many results there are. However, if there are over a thousand, how do I get the actual count? All I know is that there were at least 1,000 matches.
I need to be able to do this from within the SDK.
If you want to get total number of documents in an index, one thing you could do is set IncludeTotalResultCount to true in your search parameters. Once you do that when you execute the query, you will see the count of total documents in an index in Count property of search results.
Here's a sample code for that:
var credentials = new SearchCredentials("account-key (query or admin key)");
var indexClient = new SearchIndexClient("account-name", "index-name", credentials);
var searchParameters = new SearchParameters()
{
QueryType = QueryType.Full,
IncludeTotalResultCount = true
};
var searchResults = await indexClient.Documents.SearchAsync("*", searchParameters);
Console.WriteLine("Total documents in index (approx) = " + searchResults.Count.GetValueOrDefault());//Prints the total number of documents in the index
Please note that:
This count will be approximate.
Getting the count is an expensive operation so you should only do it with the very first request when implementing pagination.
For REST clients using the POST API, just include "count": "true" to the payload. You get the count in #odata.count.
Ref: https://learn.microsoft.com/en-us/rest/api/searchservice/search-documents
Is there a way to limit the amount of records returned via SuiteScript? I use the following method, but the search still gets all results. I am breaking out of the iteration of the results if I've hit the max I'd like to return. I can't find anything in the documentation.
In the UI it looks like one can limit the returned results, even though I haven't had much luck with it. (Maybe because I'm joining...)
var accountSearch = search.create({
type: search.Type.CUSTOMER,
columns: searchColumns,
filters: searchFilters
});
var searchResultsPagedData = accountSearch.runPaged({
'pageSize': 1000
});
var max = 9;
for (var pageIndex = 0; pageIndex < searchResultsPagedData.pageRanges.length; pageIndex++) {
var pageRange = searchResultsPagedData.pageRanges[pageIndex];
if (pageRange.index >= max)
break;
var searchPage = searchResultsPagedData.fetch({ index: pageRange.index });
// Iterate over the list of results on the current page
searchPage.data.forEach(function (result) {
}
}
Use getRange instead of each to iterate over your results. getRange lets you specify a start and end index to grab a specific slice of the results.
Why not just set the page size to the max number of results you want and only iterate over the first page (page 0)? Or if you're looking for more than 1000 results you could limit the number of pages by setting pageIndex < max; instead of pageIndex < searchResultsPagedData.pageRanges.length;
Another approach: from the comments it seems one of the issues you're having is running into the execution limit, so you could load the N/runtime module and use Script.getRemainingUsage() before each fetch to ensure you have enough governance units left - and break or return if you don't.
This is what I want to achieve:
I have a collection with a large number of documents. A user will query a certain field and this will return a large number of documents.
But for bandwidth/processing reasons, I don't want to get all documents and send them to user (browser) at once.
Lets say the user makes a GET request with a search field. This would give 1000 results. But I want to only send the first 10 to the user. And then the user would request for the next 10, and so on.
Is there a way to achieve this in Mongodb? Can I query with a certain counter and increment it in successive queries?
What is a good way to achieve this mechanism?
Thank you.
MongoDB natively supports the paging operation using the skip() and limit() commands.
//first 10 results -> page 1
collection.find().limit (10)
//next 10 results -> page 2
collection.find().skip(10).limit(10)
//next 10 results -> page 3
collection.find().skip(20).limit(10)
Here number represents 1,2,3,..... means first 10 records if you are giving number = 1.
db.students.find().skip(number > 0 ? ((number-1)*10) : 0).limit(10);
//first 10 records ,number = 1
db.students.find().skip(1 > 0 ? ((1-1)*10) : 0).limit(10);
//next 10 records ,number = 2
db.students.find().skip(2 > 0 ? ((2-1)*10) : 0).limit(10);
I've come across many of this same question here on StackOverflow. None providing a valid solid solution, so here we go:
I need to pick a random document from around 5 million documents in my MongoDB database in an efficient way.
I've tried getting the .count and using the .skip to get the random document, but it takes almost three seconds and very, very inefficient.
I can't make changes to the documents (like adding a "random") entry to each document or changing their _id's.
I've tried the solution of adding documents with an incremental _id (to pick a random _id to bypass using .skip) but this brought more headache than what it did when I try to add many documents in a short amount of time.
Adding data in an incremental way, or picking a random document, should not be this hard. I'm either missing some common knowledge, or doing something wrong, or this is what it really is..
Wanted to bring up the topic and get your responses.
Here is a way using the default ObjectId values for _id and a little math and logic.
// Get the "min" and "max" timestamp values from the _id in the collection and the
// diff between.
// 4-bytes from a hex string is 8 characters
var min = parseInt(db.collection.find()
.sort({ "_id": 1 }).limit(1).toArray()[0]._id.str.substr(0,8),16)*1000,
max = parseInt(db.collection.find()
.sort({ "_id": -1 })limit(1).toArray()[0]._id.str.substr(0,8),16)*1000,
diff = max - min;
// Get a random value from diff and divide/multiply be 1000 for The "_id" precision:
var random = Math.floor(Math.floor(Math.random(diff)*diff)/1000)*1000;
// work out a "random" _id value in the range:
var _id = new ObjectId(((min + random)/1000).toString(16) + "0000000000000000")
// Then query for the single document:
var randomDoc = db.collection.find({ "_id": { "$gte": _id } })
.sort({ "_id": 1 }).limit(1).toArray()[0];
That's the general logic in shell representation and easily adaptable.
So in points:
Find the min and max primary key values in the collection
Generate a random number that falls between the timestamps of those documents.
Add the random number to the minimum value and find the first document that is greater than or equal to that value.
This uses "padding" from the timestamp value in "hex" to form a valid ObjectId value since that is what we are looking for. Using integers as the _id value is essentially simplier but the same basic idea in the points.
i am trying to limit the number of records returned in a query:
Property.find(searchParams).nin('_id', prop_ids).limit(5).exec(function(err, properties) {
when the first call comes in, i get 5 records back. then i make a second call and pass in an array of ids (prop_ids). This array has all of the ids that were records that were returned in the first call... in this case i get no records back. I have a total of 7 records in my database, so the second call should return 2 records. How should I go about doing this?
I think mongoose might apply the limit before the nin query is applied so you will always just get those five. If it's a type of pagination you want to perform where you get 5 objects and then get 5 others, you can use the option skip instead:
var SKIP = ... // 0, 5, 10...
Property.find(searchParams, null, {
skip: SKIP,
limit: 5,
}, function(err, properties) {
})
This is what I took from your question, maybe you had something other in mind with the nin call?