Spring JPA : how can i get the last Page of an object when I do not know the total number of page - spring-data-jpa

I am trying to get the total number of pages for my Object, so that i would be able to call the last page. This was the code i used
Page<Message> firstPage = defaultMessageService.getMessage(user, user2, new PageRequest(0, 6));
paginationModel.setMessagesPage(defaultMessageService.getMessage(user, user2, new PageRequest(firstPage.getTotalPages() - 1, 6)))
.setResponseMessage("Successful")
.setSuccessful(true);
in my code i called the first page, just to get the total number of pages and subtracted the the total pages by one, to get the last page. This is resource taking as i get the list of content with the page, contents i dont intend to use. Is there a better way ? i just want the total page, size, current page

if you want only last page then sort your data in descending order and then get the first page. is it possible to sort your data then your problem will be solved.

Related

Is there a way to see if a limit offset query has reached the end with pgpromse?

I have a table of posts. I would like to query these posts as pages. Because I would like to keep my endpoints stateless I would like to do this with offset and limit like this:
SELECT * FROM post LIMIT 50 OFFSET $1 ORDER BY id
Where $1 one would be the page number times the page size (50). The easy way to check if we have reached the end would be to see if we got 50 pages back. The problem of course is if the number of pages is divisible by 50, we can't be sure.
The way I have solved this until now is by simply fetching 51 posts per query with the page size still being 50. That way if the return query is less than 51, we have reached the end.
Unfortunately, this seems a very hacky way to do this. So I was wondering, is there some feature within pg-promise or postgresql that would indicate that I have reached the end of a table without resorting to tricks like this?
The simplest method with the lowest overhead I found:
You can request pageLimit+1 rows on every page request. In your controller you will check if rowsCount > pageLimit and will know that there is more data available. Of course, before returning the rows, you would need to remove the last element and send along the rows something like a hasNext boolean.
It is usually way cheaper for the DB to retrieve an extra row of data than count all rows or make an extra request for page+1 to check if it returns any rows.
Well there is no built in process for this directly. But you can count the rows and add that to the results. You could then even give the user the number of items or number of pages:
-- Item count
with pc(cnt) as (select count(*) from post)
select p.*, cnt
from post p
cross join pc
limit 50 offset $1;
-- page count
with pc(cnt) as (select count(*)/50 + ((count(*)%50)>0)::int from post)
select p.*, cnt
from post p
cross join pc
limit 50 offset $1;
Caution: The count function can be slow, and even when not it does add to response time. Is it worth the additional overhead? Only you and the user can answer that.
This method works well only in specific settings (SPA with caching of network requests and desire to make pagination feel faster with pre-fetching):
One every page, you make two requests: one for the current page data and one for the next page's data.
It works if you for example use a React Single-Page Application with react-query where the nextPage will not be refetched but reused when user opens it.
Otherwise, if the nextPage is not reused, it's worse than checking for a total number of rows to determine whether there are any rows left as you will make 2 requests for every page.
It will even make the user interface snappier as the transition to the next page will always be instant.
This method will work well if you have a lot of page transitions as the total number of calls equals numberOfPages+1, so if on average users go to 10 pages, numberOfPages+1=10+1 or just 10% overhead. But if your users usually do not go beyond the first page, it makes little sense as in this case numberOfPages+1=2 calls for a single page.

Get current page number in ng-tables

How to get current page number the user is seeing? And when the table is refreshed it can land him on the same page instead of specifying 1st page always.
To get the current page number use: this.tableParams.page()
To set the page number use: this.tableParams.page(3)
You will need to change 'tableParams' with whatever your table object is called.
Also be mindful that if your data is dynamic and you set the page to something out of the max page range then the data will just not show.

Getting Top 3 landing pages by month and channel in 1 API request

Is it possible to get the top 3 landing pages by channel and by month in one api request? I can get all of the landing pages by channel and month, or I can get the top 3 landing pages for a certain month and channel. But I'm not sure if this is possible in one call.
fwiw I'm using python
edit:
This returns all of the paths, but I would like for it to return only the top 3 for each month per channelGrouping. I could do this in my code, but wanted to check if there was a way to do it through the api call first
results = (service.data().ga().get(
ids='ga:' + profile_id,
start_date=start,
end_date=end,
dimensions='ga:landingPagePath,ga:nthMonth,ga:channelGrouping',
sort='-nthMonth',
metrics='ga:users').execute().get('rows', [])

Range query with no dups

I have a collection that I would like to serve out as 'pages'. The collection could get quite large, I have read skip is not optimal in that case. I think range queries will work just fine in my case so I am going to try that route.
My collection will be sorted and paged on a timestamp field. I have implemented the API such that a user passes in a startDate and I will return a certain number ('limit', max of 1000) of items. However I am struggling with how to not get duplicates on each page if documents have the same time.
As an example (small page size to make it easy).
I have 6 documents let's docs 3 and 4 have the same time. If I ask for page one I will get the first three. However when I ask for page 2 with a startDate that it 'gte' the last doc on page one I will get a dup on page 2 as the last doc from page one will be that same as the first doc on page 2.
I cannot find a range query example anywhere that deals with dates, while not returning dups.

Group Page Totals and Carried Forward Totals

I have googled a lot about this but found nothing useful. This has been asked before here but noone has responded.
I have a tablix that presents grouped data with an amount column:
Tablix (data)
Name (group)
Amount (rows)
If the "Name" group spans more than one page I want to show a page total for the sum of the amounts present on the first page. On the next page the carried forward total of the previous page must be shown.
I have tried many things, especially with my custom assembly (like keeping a dictionary with the total of each group and in the footer of the report try to show the total etc). The thing that really messes up any implementation is the order where report's header, body and footer are "executed".
Any ideas or suggestions?
Due to:
The fact that there is no way to get whether one instance of the grouped data are split in more than one page at the detail level (so that the carried forward total can be shown below the repeated column headers)
The page header and footer are always "evaluated" after the body elements
You can only reference on ReportItem in the expressions used in the page header and footer
You cannot make changes to the body elements from the page header or footer (mostly because of the point above)
You cannot extend the tablix control to add your own functionality
I decided to go with showing the group page total in the footer, storing it and the picking it up to show it to the next page.
This is done by having a cumulative total column using
= IIf(RunningValue(Fields!AmountDC.Value, Sum, "Group1") <> Sum(Fields!Amount.Value, "Group1"), code.SetTotal(RunningValue(Fields!Amount.Value, Sum, "Group1")), Nothing)
which for the last detail row is setting it to "Nothing"
In the footer a textbox picks up the last value of that cumulative total field.
= code.SetTotal(Last(ReportItems!CumTotal.Value))
and stores the current total in a private field in the embedded code.
Private running As Double = 0
Public Function SetTotal(ByVal val As Double) As Double
running = val
Return val
End Function
Public Function GetTotal() As Double
Return running
End Function
And last in the page footer the stored total is picked up
= code.GetTotal()
It is too simple, but still it is the closest I could get with what I have after many trials!
Try this post ...separating pages answers..
This is not a direct answer but if youy get creative and separate the page using the sql or use a running total , this could get you started.
However to answer your question its not a feature in ssrs.