Cookie. How can I count each page visit no duplicate? - database

My page URL is with 3 variables: id=N, num=N and item=N ; N = 1, 100. They are integers and an example of URL's given:
page.php?id=1&num=24&item=12
I want to count the visit with no duplicates. How I think it's should work:
If cookie exist don't add a new value to database, else set cookie and increment value in database.
I used a $_COOKIE[''] array, to identify if page was visited:
$_COOKIE['product[id]'] = $_GET['id'];
$_COOKIE['product[num]'] = $_GET['num'];
$_COOKIE['product[item]'] = $_GET['item'];
The problem appeared when the path it's different:
page.php?id=1&num=24&item=12&page=0#topView
I can't query the data base each time when a person access the page, it's because there are, 1000+ unique visits.
My questions is: how can I count in mod unique each page visit?
Note:
page.php?id=1&num=24&item=12
or
page.php?id=1&num=24&item=15
or
page.php?id=2&num=24&item=12
these links gives me an unique product info, depending by variables.
Thank you!

Since my comment is the solution for your problem, I am converting it as an aswer.
"I can't query the data base each time when a person access the page, it's because there are, 1000+ unique visits." - I doubt you can. In my opinion - you should. Count all the page accesses and when you want to grab the final results, do grouping by ip, id, num, item. Putting all the data into the database will also give you a brief view of the most popular pages. Even further, you will be able to see what pages are being accessed more times by one unique user and identify the reasons. The more data is better. It won't take much of your database.
There is a mistake in your finally decided algorithm. Imagine the id is 11, num is 5 and item is 7. And another with id = 1, num = 15, item = 7. Hope you see what I mean. :P Put it like that
md5($_GET['id'].'-'.$_GET['num'].'-'.$_GET['item']);
so it is really unique.

Related

No other way than dropping the duplicates, if ValueError: Index contains duplicate entries, cannot reshape?

enter image description here
Hi everyone, this is my first question.
I'm working on a dataset from patients who undergone urine analysis.
Every row refer to a single Patient Id and every Request ID could refer to different types of urine analysis (aspect, colour, number of erythrocytes, bacteria and go on).
I've add an image to let you understand my dataset.
I'd like to reshape making one request = one row , with all the tests done in the same request on the same row.
After that I want to merge with another df, that I reshape by Request ID (cause the first was missing a "long result" column, that I downloaded from another software in use in our Hospital).
I've tried:
df_pivot = df.pivot(index='Id Richiesta', columns = 'Nome Analisi Elementare', values = 'Risultato')
df_pivot.reset_index(inplace=True)
After I want to do --> df_merge = pd.merge (df_pivot,df,how='left', on='Id Richiesta')
I've tried once with another dataset, but I had to drop_duplicates for other purpose, and it worked.
But this time I have to analyse all the features.
How can I do? Is there no other way than dropping the duplicates?
Thank you for any help! :)
I've studied more my data and discovered 1 duplicate of bacteria for the same id request (1 in almost 8 million entries....)
df.drop_duplicates[df[['Id Richiesta', 'Id Analisi Elementare', 'Risultato']].duplicated()]
Then visualized all the rows referring at the "Id Richiesta" and the keep last (they were the same).
Thank you and sorry.
Please, tell me if I had to delete this question.

Pagination and Entity Framework

In my mobile app, I try to retrieve data from a table of my SQL Server database. I'm using EF and I try to use pagination for better performance. I need to retrieve data from the last element of the table. so if the table has 20 rows, I need, for page 0, IDs 20, 19, 18, 17, 16 then for page 1 IDs 15, 14, 13, 12, 11 and so on...
The problem is this: what if, while user "A" is downloading data from table, user "B" add row? If user "A" get Page 0 (so IDs 20, 19, 18, 17, 16), and user "B" in the same moment add row (so ID 21), with classic query, user "A" for page 1 will get IDs 16, 15, 14, 13, 12... so another time ID 16
My code is very simple:
int RecordsForPagination = 5;
var list = _context.NameTable
.Where(my_condition)
.OrderByDescending(my_condition_for ordering)
.Skip (RecordsForPagination * Page)
.Take (RecordsForPagination)
.ToList();
Of course Page is int that come from the frontend.
How can I solve the problem?
I found a solution but I don't know if it's the perfect one. I could use
.SkipWhile(x => x.ID >= LastID)
instead
.Skip (RecordsForPagination * Page)
and of course LastID always is sent from the frontend.
Do you think that performance is always good with this code? Is there a better solution?
The performance impacts will depend greatly on your SQL Index implementation and the order by clause. But its not so much a question about performance as it is about getting the expected results.
Stack Overflow is a great example where there is a volume of activity such that when you get to the end of any page, the next page may contain records from the page you just viewed because the underlying recordset has changed (more posts have been added)
I bring this up because in a live system it is generally accepted and in some cases an expected behaviour. As developers we appreciate the added overheads of trying to maintain a single result set and recognise that there is usually much lower value in trying to prevent what looks like duplications as you iterate the pages.
It is often enough to explain to users why this occurs, in many cases they will accept it
If it was important to you to maintain the place in the original result set, then you should constrain the query with a Where clause, but you'll need to retrieve either the Id or the timestamp in the original query. In your case you are attempting to use LastID, but to get the last ID would require a separate query on it's own because the orderby clause will affect it.
You can't really use .SkipWhile(x => x.ID >= LastID) for this, because skip is a sequential process that is affected by the order and is dis-engaged the first instance that the expression evaluates to false, so if your order is not based on Id, your skip while might result is skipping no records at all.
int RecordsForPagination = 5;
int? MaxId = null;
...
var query = _context.NameTable.Where(my_condition);
// We need the Id to constraint the original search
if (!MaxId.HasValue)
MaxId = query.Max(x => x.ID);
var list = query.Where(x => x.ID <= MaxId)
.OrderByDescending(my_condition_for ordering)
.Skip(RecordsForPagination * Page)
.Take(RecordsForPagination);
.ToList();
It is generally simpler to filter by a point in time as this is known from the client without a round trip to the DB, but depending on the implementation the filtering on dates can be less efficient.

Laravel skip and delete records from Database

I'm developing an app which needs to record a list of a users recent video uploads. Importantly it needs to only remember the last two videos associated with the user so I'm trying to find a way to just keep the last two records in a database.
What I've got so far is the below, which creates a new record correctly, however I then want to delete all records that are older than the previous 2, so I've got the below.
The problem is that this seems to delete ALL records even though, by my understanding, the skip should miss out the two most recent records,
private function saveVideoToUserProfile($userId, $thumb ...)
{
RecentVideos::create([
'user_id'=>$userId,
'thumbnail'=>$thumb,
...
]);
RecentVideos::select('id')->where('user_id', $userId)->orderBy('created_at')->skip(2)->delete();
}
Can anyone see what I'm doing wrong?
Limit and offset do not work with delete, so you can do something like this:
$ids = RecentVideos::select('id')->where('user_id', $userId)->orderByDesc('created_at')->skip(2)->take(10000)->pluck('id');
RecentVideos::whereIn('id', $ids)->delete();
First off, skip() does not skip the x number of recent records, but rather the x number of records from the beginning of the result set. So in order to get your desired result, you need to sort the data in the correct order. orderBy() defaults to ordering ascending, but it accepts a second direction argument. Try orderBy('created_at', 'DESC'). (See the docs on orderBy().)
This is how I would recommend writing the query.
RecentVideos::where('user_id', $userId)->orderBy('created_at', 'DESC')->skip(2)->delete();

GWT how to setup Pager in DataGrid when using Objectify Cursors

I recently got it to the point where I can retrieve data with a Cursor (see this link: GWT pass Objectify Cursor from Server to Client with RequestFactory and show more pages in DataGrid)
what I am running into - when I get the data pack on the client side its only a List of 25 - when I go to set the data in the DataGrid the pager on the bottom says showing 1-25 of 25, there are obviously more records in the database I'm just retrieving 25 of them at a time with the cursor
What I tried doing is setting the following:
pager.setRangeLimited(false);
Unfortunately - while this allows me to page and select more from the database - it never actually gives me the amount in the database. What I am wondering is, if I'm using a Cursor on the server side - how do I set the total count in the Pager??
One thing i thought about doing is simply adding a total count variable to the ListCursor wrapper object i'm returning - unfortunately this would require that if i request it with a null initial query i go through and get the total count every time - this seems horribly inefficient - and then once i get this back I still have no idea how to actually tell the pager that more data is available than i actually gave it.
Any help on this would be really appreciated
You set the total count in the pager by telling the pager that the row count is exact :
asyncDataProvider.updateRowCount(int size, boolean exact);
If you don't tell the pager that the row count is exact, then you can obviously not navigate to the last page.
The core issue is how to get hold of the total row count. Querying the row count is indeed highly inefficient. A better bet would be to keep a counter in the data store that tracks the number of records. This can be quite inefficient too, because you have the increment this counter synchronized/transactional.
In my project, I dont keep track of the exact row count but I provide flexible search options.

How do travel websites implement the sorting of search results?

For example you make a search for a hotel in London and get 250 hotels out of which 25 hotels are shown on first page. On each page user has an option to sort the hotels based on price, name, user-reviews etc. Now the intelligent thing to do will be to only get the first 25 hotels on the first page from the database. When user moves to page 2, make another database query for next 25 hotels and keep the previous results in cache.
Now consider this, user is on page 1 and sees 25 hotels sorted by price and now he sorts them based on user-ratings, in this case, we should keep the hotels we already got in cache and only request for additional hotels. How is that implemented? Is there something built in any language (preferably php) or we have to implement it from scratch using multiple queries?
This is usually done as follows:
The query is executed with order by the required field, and with a top (in some databases limit) set to (page_index + 1) * entries_per_page results. The query returns a random-access rowset (you might also hear of this referred to as a resultset or a recordset depending on the database library you are using) which supports methods such as MoveTo( row_index ) and MoveNext(). So, we execute MoveTo( page_index * entries_per_page ) and then we read and display entries_per_page results. The rowset generally also offers a Count property which we invoke to get the total number of rows that would be fetched by the query if we ever let it run to the end (which of course we don't) so that we can compute and show the user how many pages exist.

Resources