I have a JSF application where every site visitor (whether it's a registered user or not) can leave multiple comments and rate existing comments (thumbs up/down). I want to limit the comment ratings to one rating per comment per visitor per day. Can you recommend me the best way to do this? Should I try to log the IP address, or the MAC address (if possible), or something else? Should I save the data in my DB or user the cookies (or something else)?
Relevant tables and fields:
article (id, title, body...)
comment (id, article_id, user_id, text...)
user (id, username...)
// This structure can be changed if needed
Thanks!
Related
I'm currently working on a website and I have used PostgreSQL, Express and Node.js technologies to make it.
I want to make an achievement system that is event based. E.g. a user makes a new post and is awarded an achievement/badge for making the first post. I was wondering what the code logic behind this would be? How do I award the user when first post is made? And the next time when user makes a new post again (second post) check if the user already has the achievement/badge for making the first post and just continue without awarding the achievement/badge again?
My database tables
The badges table looks like this:
id name description icon created_at updated_at
user_badges table
user_id
badge_id
created_at
updated_at
users table
id name etc...
Any help would be much appreciated.
You shoould have one user table that will store user data and with that you should have an column like totalQaAsked or badgeGiven like this
user's table
username, userFullName, userLoggedIN, totalQaAsked, badgeGiven
At the first time totalQaAsked would be 0 so badgeGiven would be false when user ask his first question then you should have one table that will track question asked by the user and check weather this the first question asked by the user then it will update user's table with totalQaAsked+1 and badgeGiven=true. now you'll have user's data every time you proceed then you can check easily.
Question's table
username, question, some more columns
2nd Method
You can directly query from question with user's id and check how many question asked by the user then you can give badge according to it.
I'm building an activity feed application, where a user can like/comments on each activity feed. I went through GetStream.io documentation and looks like I'll have to send the activity with object ids.
{
id:"ef696c12-69ab-11e4-8080-80003644b625",
actor:"User:1",
object:"Comment:12",
started_at:"2014-11-11T15:06:16+01:00",
target:"Feed:100",
time:"2014-11-11T14:06:30.494",
verb:"add"
}
User:1 and Feed:12 are the objects in my application database? Does it mean that, while retrieving activities, I'll have to hit my database to retrieve the complete feeds?
Say the Feed:12 had few likes and comments earlier from other users. How do I get the complete set of likes/comments on user timeline feed?
What if I want to customize the view, say I want to show all users (image, name, the profile like etc) along with comment with timestamp similar to FB? Do I need to send these attributes as additional parameters for each feed?
Thanks,
Yes, when you fetch a feed from Stream and we give you back these references like user:1 or comment:12, we expect that you'd "enrich" those details from your database.
Typically what our users do is track the name of the model (eg, user) and the user_id (eg, 1). When you get the feed and put it into a hash map, you'll iterate over the activities, pull out all of the actor attributes, and do a single lookup like select * from user where id in (1,3,5,6,9,12) so that you're only hitting your database one time for all user objects or all comment objects or whatever. Then, replace those activities in your hash map so now you'd have actor: <object for User 9> and any other attributes you'd need for your UI presentment.
Then do the same for other references you pass in the activity, and so on.
Things we DON'T recommend are putting in string references for things that could change on your side. For example, if you had actor: "user:ian" instead of my user_id, if I ever change my username later then things probably wouldn't work properly on your side.
I'm doing a notification system for my website.
A notification systeme like facebook. Or stackoverflow.
I have 2 problems.
How store in db ? I can store ALL notifications in the user document ? or in a document apart (because i think monogdb is limited for size in a document ?) Or, store intelligently ? (using inc, or a value (see: true/false) in db, with query sophisticated)
How do for brought at the page ? For exemple, when i click in a link in my inbox for stackoverflow, i'm redirect to the page. But me, i have a system that is multipage for exemple: I have 100 friends. There are listed 30 per page. So when i click on the notification i can't redirect to the because it's impossible to know the good page (users can be removed).
Thank you very much !
And if you have another ideas, tell me. Thanks.
EDIT:
(sorry for my english, i'm french)
For the first problem, i realize that i have to wait the time comes to choose my structure. Because my notification is .. a little complicated, so advance to the feeling.
For the second, i solved the problem. I explain:
(I take the exemple of friends because it's easy to undestand.)
I stored my data like this:
{
friends: [
{_id: xxxxx, ts: xxxx},
{_id: xxxxx, ts: xxxx}
]
}
Imagine i display all friends: 30 per page.
The problems are:
when i want to display all friends i cant sort using mongo. (a little problem)
If i want to lead a user to this list (30 per page) at a special friend, always keeping the sort by ts. I can't know the page. The uniq solution is to take all document.
But: veryyy bad in performance.
So, i store like this:
{
friends: {
xxxx: {ts:xxx},
xxxx: {ts:xxx}
}
}
Know i can sort the document, with use skip and limit.
So if i want a portion, i do not need to take all documents.
To know the page, i just do the number of < or > to the ts, i have for exemple 11 friends who are > to the ts of the friends that i want, and do a count for all friends (ex: 50 friends) with 50 and 11, i can guess the page.
Is this solution is good ?
- i need a count
- a query to know the number of > or <
and i can take the page where is listed the friend, keeping the sort ts
You can don't understand why i use a count. I need because they are not store in the same docment.
2 EDIT:
The problem with this solution, is that i need to make query object and update object outside of the mongo query (ex: for do friends.xxxxxx: {$exists:true}
ps: And what advantages are to use ts instead of date for mongodb ?
I'm using ts but i think i will store date, and no ts.
3 EDIT
I will do like Sammaye. Store in separate document. Take a look at: http://mongly.com/Multiple-Collections-Versus-Embedded-Documents/#1 and http://openmymind.net/2012/1/30/MongoDB-Embedded-Documents-vs-Multiple-Collections/
#Stennie make a pretty complete answer.
However recently I did a similar thing in PHP for my website. The first thing to understand is whether you are doing a notification system or a wall (the two are very different), it seems unclear to me and I am not sure what you mean by:
How do for brought at the page ? For exemple, when i click in a link
in my inbox for stackoverflow, i'm redirect to the page. But me, i
have a system that is multipage for exemple: I have 100 friends. There
are listed 30 per page. So when i click on the notification i can't
redirect to the because it's impossible to know the good page (users
can be removed).
That is not very good English and is very confusing when I read it. If you can expand on that I am sure people can answer better.
For a notification system I found that a large collection of notification objects also worked. So I had a schema like:
{
_id: {},
to_user: ObjectId{},
user_id: ObjectId{}, // Originating user
custom_text: "has posted a new comment on your wall post",
read: false,
ts: MongoDate()
}
And this would literally be the document I have to produce notifications. Each time a user commits an action that generates a notification it writes a new row to the DB with to_user being populated each time with each user needing to be notified. As for multiple users commiting the same action I actually convert the user_id field in a list of OjbectId's so I can say:
Sam, Dan and Mike all commented on your wall post
I then query by ts storing the last ts that the user looked at in their row allowing me to do a range based query on the newest notifications each time. This works quite well for sharding and querying in my personal experience.
Hope it helps,
Whether to embed or link is a common question for data modelling in MongoDB. If your number of notifications is going to be unbounded, you are likely going to be better saving these in a separate collection.
The current 16Mb document limit actually isn't as much as an issue as some other considerations:
A performance issue you may encounter by including all notifications in a single document is that fast-growing documents may also need to be relocated in the database more frequently (see Padding Factor).
You may want to be applying multiple updates to a document (such as setting a "read" flag on notifications) in a very short period of time, which means more contention for updating the same document (see Atomic Operations).
In order to implement paging you can use limit() in combination with a range query or skip(). A range query (eg. based on an indexed notificationDate) will make more effective use of indexes and perform better than skip() as your collection grows.
I have a database of clients. Before entering a new client, I want to make sure that that client is not already in the database. So I want to put a search form at the top of my page to search by client number, and client name. Further down the page, I'll have another form to enter and submit the client's information. Would this be the best way to go about something like this? How would you approach this? i'm using drupal 6.
It is better that when the user is inserting a new customer name, an autocomplete shows the names matching the characters inserted by the user; if the user wrote "Mic", and in the database there is a customer with the name "Michael Greenpeace", the autocomplete will show "Michael Greenpeace", and the user will understand there is already a record for that customer.
Even without the autocomplete (which would help the user to understand if the data for the customer has been already inserted in the database, and continue with the next customer), a user that inserted the name of an existing customer should see the existing data; this would help the user to avoid rewriting data that are already updated (customer information need to be updated, sometimes, and not only inserted).
I have created a custom User profile template and object in the core database in Sitecore (as per the Security API Cookbook).
I can select this programmatically (as per the Security API Cookbook) so that my extranet users have an extended profile, that covers all the usual suspects (Address, phone, email format etc.)
However, where is this data stored? And how do I access it if I want to query the database to return a subset of users based on this profile data.
A typical requirement for an extranet member system is to extract a list of users to contact either in an email or a phone type campaign. Can this be done with the Sitecore membership system?
UPDATE>
I'm going to take a guess and say the profile data is stored in aspnet_Profile.PropertyValuesBinary .. which would make it nigh on impossible to query and not suited to my purpose. That is unfortunate. So to extend my question, if that is the case, is it possible to get Sitecore to store those values in the text field so they are searchable?
The standard Microsoft implementation of the SqlProfileProvider (which is used in Sitecore by default) stores the user profile information in the aspnet_Profile table. All the properties are serialized into the PropertyNames / PropertyValuesString columns. The PropertyValuesBinary is used to store the binary data (images). You can find more details if you look at the code of System.Web.Profile.SqlProfileProvider, SetPropertyValues method.
Next, all the custom properties you define in the user profile, are serialized to the SerializedData property of the Profile class, and it is again serialized to the PropertyNames / PropertyValuesString columns like any other property.
Also, couple of properties are stored in aspnet_Membership table (for some reason) - Email and Comment.
So, if you are going to query the users by Email, you can use FindUsersByEmail method of MembershipProvider. Otherwise, if you plan to filter by another property value, I suppose, you'll have to get all users and filter the obtained collection.
Hope this helps.
I faced this exact problem last week, didn't come up with a permanent solution, but to solve my particular issue, I wrote a little helper page and added it as a Sitecore application to be accessed from the CMS interface. All it did was query all users, and determine if they had any of like 5-6 profile properties assigned.
var userList = Sitecore.Security.Accounts.UserManager.GetUsers();
That is the relevant line to grab the users, it returns Sitecore.Common.IFilterable
So if you need to do something where you're grabbing profile info from all users, you cn do something like this:
foreach (Sitecore.Security.Accounts.User user in userList)
{
Sitecore.Security.UserProfile profile = user.Profile;
string whatever = profile["Whatever"];
//add whatever to a list or something
}
This worked out very well for my purposes, but I don't know how feasible it will be in your situation.