I have an iOS app that presents content in a tableView. I've added a 'like/dislike' feature that interacts with my database (I use Parse.com). Every time someone likes/dislikes a piece of content, the specifics are sent to the Parse database. For each piece of content, I'd like to calculate and display the percentage of 'likes' over 'likes' + 'dislikes'. This is pretty simple math, but I can't wrap my head around the best way of designing my database table and the most efficient way to calculate the 'liked' percentage for each piece of content before the tableView physically appears.
As it is, I already have a loop in my tableView's viewDidLoad which compares the content from another database table to the 'like/dislike' table to restore the 'like/dislike' button state of the user (if they already liked/disliked a piece of content).
At first, I thought of creating an array in the initial viewDidLoadloop. However, using the whereKey: equalTo: type of query for each piece content to simply find the amount of likes/dislikes takes forever. As predicted, it is very slow in cellForRowAtIndexPath as well.
Worst case, I can make these calculations server-side and just pull the 'liked' percentage. However, I'd like to implement this in the app somehow. I'm a complete beginner, so I may be going about this all wrong.
Here is the basis of my database table:
Edit: I've managed to build a server-side program that calculates the percentage of users that 'like' pieces of content. My app pulls this percentage from the database at runtime. To make the percentage change more responsive when the user 'likes' something, I locally calculate an updated percentage. The problem here is when the user exits the app and reopens, the data reloads. If the server-side program had not run recently, the app will display an old 'liked' percentage (the most up to date % would not be calculated yet). The two solutions I see to fix this are:
Run the server-side program every 1-3 min
Post more data to the database when someone likes content (this would involve additional database queries for every single 'like').
I think both of these options are way too expensive for what I'm trying to accomplish.
I'd suggest leaving the calculations to the server side, and responding with the information to utilize in the app. This will save you from processing and parsing the incoming results.
You have greater processing power on a Server than on a device.
Related
I have two screens:
Homefeed.dart
Profile.dart
On Homefeed screen all the data from various users is fetched from a server and is shown in a list of cards form.
On the Profile screen, only data that belongs to the logged in user is fetched.
The problem is that, there will be an overlap in the data that is fetched on the both the screens. For example if a user writes a post, it can show up on the Homefeed. Now if the user decides to perform any action such as like, delete, edit etc on thir post from the profile screen, then it should also update the same post that was fetched on the Homefeed screen.
Now unless user explictly refreshes the data, and send a request to server to fetch the updated data, what would be an ideal way to achieve this synchrony.
I did consider using a realtime database, but this will mean migrating current project and it might get expensive and might have problem of it own.
The other "hacky" way would be to maniuplate data somehow (I still havent figured it out) on the client side and show the update instead of fething new data from the server.
Or some other, more ideal way of achiving this, that I don't know of.
The best way is to reflect any changes of the user post i.e edit, delete in Profile.dart is by updating the database without tricking the just in the client side. Because you may reduce the database calls by tricking, but you are giving high chances of inconsistent data in database. Your database wouldn't be reliable.
Database should be the single source of truth
I would suggest, Every time HomeFeed.dart page is loaded , try loading the latest data from the database. If you are using real-time database, you dont have to check on every page load.
I am trying to implement infinite scrolling for documents stored in a MongoDB collection. Every document is a restaurant that has a numeric field rating, so I am using the rating field for sorting and showing restaurants with the highest rating first.
The problem is that the collection of the restaurants is not static. The ratings of the restaurants change in real time, therefore the order of the restaurants in the collection changes constantly. As a result, although I formally have the sorting key, it does not make much sense.
I am thinking of 2 solutions of the problem:
Accept that the order of the restaurants may change slightly while someone is doing the infinite scrolling. Make the front end responsible for getting rid of possible duplicates. Accept that some of the restaurants may not appear during a scrolling at all. But that looks more like working around the problem instead of solving it.
Only perform infinite scrolling against a static copy of the collection of restaurants. Update the static copy periodically (e.g., once a day) with the rating updates. But this approach seems overengineered. Also, what happens with the infinite scrolling at the moment when the static copy of the restaurants gets updated with the new ratings? Such scrolling will be broken as well because the problem with the changing order is still here, the order just does not change that frequently.
I am sure I am far not the first one who have faced this problem. After all, there are a lot of examples of infinite scrolling implementations out there, like Facebook or Instagram feeds. At the same time, all the articles I have read so far seem too superficial and covering only cases with infinite scrolling through static collections.
What is the right approach to deal with infinite scrolling for a collection that may change its order any time?
Thank you.
Infinite scrolling, as commonly implemented, isn't a precision navigation method to begin with. Who are your users?
Power users are likely to hate it (I do on github, facebook, etc.) hence won't be using it too much.
Non-power users won't be able to tell that data is missing. If they happen to be looking for a particular restaurant and it vanishes, telling them to reload the page will be a sufficient explanation for most.
Users who scrape your data will do it without delays between requests to get all of your data.
When you show the same restaurant twice people will notice so check for those cases in the frontend.
You may also consider having a high-precision rating field for sorting. For example, if normally your UI shows integer rating, keep the floating-point rating used during the calculation and sort by that. This will produce a more stable sort.
What would be the best way to store daily health related data (height, weight, calories burned, hours of sleep) in a Parse (MongoDB) database? The user will update their health data up to 10-15 times a day and I am unsure how to track their data in real time without having to create a new record every time they update only a certain piece of information. Currently I have a User class and a HealthProfile class, which contains basic information about height, weight, etc.
I could collect the data over the course of the day and then save it in the database at night however this will not work for database driven charts I want to display.
Data Interaction will be as follows: throughout the day a user inputs how much exercise they did, food they ate, etc. and the app will display a line/bar chart showing their progress/calories burned (or other health figures) for the day, week, and month. It will also include things like blood pressure and other measurements and I want to be able to store all of these things for a user and allow them to view their history, as well as input new data, at any time. It is a similar concept to how Apple's Health app works.
I will need to make sure the user's data is always persisted in a database so if they login on their phone or the website, their data is always up to date, so writes to the database will need to be upon user input and reads will take place any time the user view a chart or figure.
You really need to work out how you want to interact with the data. That will determine the best way to store it.
Once you have a clear picture of the different ways you want to read/write/use the data come back and ask clear questions to get help... currently it isn't clear what sort of help you want.
So we run a downline report. That gathers everyone in the downline of the person who is logged in. Some people of clients run this with no problem as it returns less than 100 records.
Some people of clients however returns 4,000 - 6,000 rows which comes out to be about 8 MB worth of information. I actually had to up my buffer limit on my development machine to handle the large request.
What are some of the best ways to store this large piece of data and help prevent it from being run multiple times consecutively?
Can it be stored in a cookie?
Session is out of the question as this would eat up way to much memory on the server.
I'm open to pretty much anything at this point, trying to better streamline the old process into a much quicker efficient one.
Right now what is done, is it loads the entire recordset, it loops through the recordset building out the data into return_value cells.
Would this be better to turn into a jquery/ajax call?
The only main requirements are:
classic asp
jquery/javascript
T-SQL
Why not change the report to be paged? Phase 1: run the entire query, but the page only displays the right set of rows based on selected page. Now your response buffer problem is fixed. Phase 2: move the paging into the query using Row_Number(), now your database usage problem is fixed. Phase 3: offer the user an option of "display to screen" (using above) or "export to csv" where you can most likely export all the data, since csv is nice and compact.
Using a cookie seems unwise, given the responses to the question What is the maximum size of a web browser's cookie's key?.
I would suggest using ASP to create a file on the Web server and writing the data to that file. When the user requests the report, you can then determine if "enough time" has passed for it to be worth running the report again, or if the cached version is sufficient. User's login details could presumably be used for naming the file, or the Session.SessionID, or you could store something new in the user's session. Advantage of using their login would be that your cache of the report can exist longer than a user's session.
Taking Brian's Answer further, query page count, which would be records returned / items per page rounded up. Then join the results of every page query on client side. Pages start at a offset provided through the query. Now you have the full amount on the client without overflowing your buffer. And it can be tailored to an interface and user option (display x per page).
We're using Crystal 11 through their webserver. When we run a report, it does the Sql query and displays the first page of the report in the Crystal web reportviewer.
When you hit the next page button, it reruns the Sql query and displays the next page.
How do we get the requerying of the data to stop?
We also have multiple people running the same reports at the same time (it is a web server after all), and we don't want to cache data between different instances of the same report, we only want to cache the data in each single instance of the report.
The reason to have pagination is not only a presentation concern. With pagination the single most important advantage is lazy loading of data - so that in theory, depending on given filters, you load only what you need.
Just imagine if you have millions of records in your db and you load all of them. First of all is gonna be a hell of a lot slower, second you're fetching a lot of stuff you don't really need. All the web models nowadays are based on lazy loading rather than bulk loading. Think about Google App Engine: you can't retrieve more than 1000 records in a given transaction from the Google Datastore - and you know that if you'll only try and display them your browser will die.
I'll close with a question - do you have a performance issue of any kind?
If so, you probably think you'll make it better but it's probably not the case, because you'll reduce the load on the server but each single query will be much more resource consuming.
If not my advice is to leave it alone! :)