Paging with a data set that can be changing? - database

I'm sure there is something out there about this topic but I just can't figure out how to word a search for it.
I have a table of records that gets loaded into a paging grid in the UI. The user has the ability to update/modify these records..also multiple users can use the system at once all hitting the same data. I have a filter on the paging grid allowing the user to see only X type of records.
When the user first enters with filter X selected they see items 1-25 on page 1 of 2. They page to the second page where the items should be 26-50..but before they paged lets say 25 records on the first page had their type changed by another user, now they don't appear when selecting that filter. So now we have 25 less items to page through which means items that were 26-50 before are now items 1-25 and what was page 2 is now page 1 and there is no page 2...
You can probably see the issue I'm getting into, I'm passing an offset to the query to get the next page of results..but now that offset is so high it returns a blank page of records confusing the user and our record processing.

There isn't really an easy solution to this problem. Even GMail/Google doesn't show the exact number of messages/pages found when searching something.
The first thing you can do (if you use a DataGrid/CellTable) is set the boolean exact as false when you call updateRowCount, and give it your current number of records instead of your total number of records. This will make the pager display "1 - 25 of over 25" instead of "1 - 25 of 50".
The next possibility is to update the row count regularly (using RPC polling to check for new/deleted records - or using server push techniques, see GWTEventService and ServerPushFAQ).
You can also check if your request returns items or not, and cancel the call/update the row count if it doesn't.

Related

smart-table - custom pagination

I am using smart-table plugin for pagination.
My requirement is- i am fetching 100 records from database while loading and records per page is 10.
So, number of pages would be 10 in pagination.
Now, i want when i click on the page number 10 (from pagination) then i want to fetch the another 100 records from database & then those new 100 records will append in the table ( total records in table would be 200 and page number would be 1 to 20 in the pagination) and same for when i click on page number 20, another 100 records fetch from database and so on.
What I understood from your question is that you want the table rows to stack on one another instead of being replaced when you navigate on the paginator.
First of all, you don't need to use the default pagination, you can put your own custom markup in the <tfoot> tags
Second, if you want to show different amounts of rows on click, you could use the limitTo filter on the ng-repeat
Here's a plunk showing how I've added buttons that change the amount of rows being displayed on the table. you can use this logic (and functions) on your own template, just fetch the page number you going for, multiply by 10, and set that number as the amount you want to see

How to get all records when using pagination

Let's say I set a limit of 10 per page on a set of records retrieved with $results = $this->paginate('ModelName'). The total number of records matching the paginate/find parameter is 30, so 10 records show up on each of the pages. When I look at $results, it contains only 10 records displayed on the page.
Is there a way to get all 30 records in the view without having to separately do something like $allResults = find('all', $params) followed by $this->set('everything', $allResults)?
I ended up passing some of the pagination parameters that can be used to retrieved all of the 30 records from the view via a form to an action.
So, the user clicks on a form on the view that submits hidden variables to an action, where the whole set of 30 records are retrieved and desired operation is performed. Then, the page is redirected to the previously paginated view.

How do I store this in Redis?

I have many products (product_id). Users (user_id) view the products.
I want to query which users viewed whatever product in the last 24 hours. (In other words, I want to keep a list of user_ids attached to that product_id...and when 24 hours is up for a user, that user pops off that list and the record disappears)
How do I store this in Redis? Can someone give me a high-level schema because I'm new in Redis.
For something similar I use a sorted set with values being user ids and score being the current time. When updating the set, remove older items with ZREMRANGEBYSCORE as well as updating the time score for the current user.
Update with code:
Whenever a new item is added:
ZREMRANGEBYSCORE recentitems 0 [DateTime.Now.AddMinutes(-10).Ticks]
ZADD recentitems [DateTime.Now.Ticks] [item.id]
To get the ids of items added in the last 10 minutes:
ZREVRANGEBYSCORE recentitems [DateTime.Now.Ticks] [DateTime.Now.AddMinutes(-10).Ticks]
Note that you could also use
ZREVRANGE recentitems 0 -1
if you don't mind that the set could include older items if nothing has been added recently.
That gets you a list of item ids. You then use GET/MGET/HGET/HMGET as appropriate to retrieve the actual items for display.
If you want redis keys to drop off automatically then you'll probably want to use a redis key for every user_id-to-product_id map. So, you would write by doing something like redis.set "user-to-products:user_id:product_id", timestamp followed by redis.expire "user-to-products:user_id:product_id" 86400 (24hrs, in seconds).
To retrieve the current list you should be able to do redis.keys "user-to-products:user_id:*"

How to combine two search results effectively?

I'm programming a site in PHP/MySQL that gets search results for products via API from an external site. This site also will have it's own products and the owners of the site want the search results to be inter-connected.
If someone searches for VIDEO, ordered by date then the results should be all in order regardless of the source it came from.
eg.
July 31 - Video A - our database
July 30 - Video B - via API
July 29 - Video C - via API
July 28 - Video D - our database
...
The problem I'm having is figuring out a way to do this effectively especially regarding viewing multiple pages of results. If someone clicks to the 2nd page of results then I need to figure out the last item on the first page of results (and the last item from the API), then only get the items from the API starting after the last API item viewed on the previous page and then do the same for our database results and re-combine them again.
In order to avoid this complex algorithm, another idea I had was to limit the results to a large amount - like 500 results and grab them all at once and order them. Then if the user goes forward a few pages, I do not have to re-grab all the data.
Does anyone have suggestions on good algorithms to use to combine two search results?
Whether you use it for caching or not, you will need to grab at least a page worth of results from both sources, in case all the next results will come from that source.
Grabbing a lot of results and caching them (in the session) is one solution you could use.
If for some reason you don't want to cache all the results (if the operation is expensive and you need this optimized), you could store a simple array in the session that contains the location of the results, and then you would know the starting number for the next page.
For example (pseudo code)
**Request 1**
Get 10 results from API
Get 10 results form Database
Merge the results
Display first 10 and save the order to an array
(A for API, D for Database, ex: A,A,A,D,A,D,D,A,D,A)
User clicks page 2
**Request 2** (Page 2)
Get 10 results from API starting at 5
Get 10 results from Database starting at 7
Repeat merge and display above.
You could also optionally cache what you have needed to retrieve so far (and you will have 10 extra results). This would make the first request longer, but could possibly make the second request much faster.
If the user jumps forward several pages, you would need to get the largest number of results that could have been displayed in the preceeding unknown pages from each source.
If you are not too worried about performance from either source, I would retrieve up to a large number like you said and cache all results temporarily. As soon as a new search is executed, dump the old results.

problem of conditional visibility and page breaks with rectangles in SSRS 2005

I am trying to insert a conditional page break, actually i had a report of 50 pages with invoices each invoice is 3 pages long so i need a paghebreak for the 2nd invoice t printon the next page as i need the whole report ot print back to back,so i inserted one page break,so this starts the next invoice to start on 4th page but i want next invoice to start on 5th page which is a new page and i inserted another pagebreak there if the 3rd page of previous report is not filled, but if the 3rd page is filled and the invoice goes on to 4th page then i dont need this additional page break
I tried doign this by taking two rectangles
--first with inert page break at the end
--second with conditional visibility of the rectangle2 and with page break at the start.
and the condition for the rectangle2 to be visible is like
Visibility---hidden and expression is
--iif(count(id field of the table in third page)>=24,true,false)
i.e 3rd page accomodates atmost of 24 records and if the records are more than 24 i dont need another pagebreak and i am hiding the rectangle2 only if records are less than 24 i need another page break and i am not hiding the rectanlge2
BUT THE VISIBILITY IS NOT WORKING AND THE RECTANGLE2 IS NOT WORKING.
Please help me with this..
You should be able to add a column to the data source, such as InvoiceNumber, that you could define as a page-breaking group. Then the page should break before a new Invoice and at the end of each of your rectangles.
This is a known problem with SSRS 2005. It's very unfortunate actually. Have a look at my question here.

Resources