I have a Product table with columns "ProductId(pk), P_Name, Price, Quantity"
and another table VoteLogs with columns "V_id(pk), ProductId, UserId, Vote"
I've implemented the rating feature by following this tutorial
The Vote Log table contains the following data
As you can see [email protected]
and [email protected]
both voted product 28
but [email protected]
has also voted product 20, 72, 1187, and 1188
Now when [email protected]
log in, I want to display him product 20, 72, 1187, 1188
because customer1
and customer2
both voted the same product so they might have similar taste.
I have tried and came this far,
public ActionResult BasedOnRating()
{
string UserId = User.Identity.GetUserName(); //logged in with [email protected]
var query = from vv in db.VoteLogs
join pp in db.Products
on vv.ProductId equals pp.ProductId
where !(db.VoteLogs.Where(c => c.UserName == UserId)
.Select(c => c.Product.ProductId).ToList())
.Contains(vv.Product.ProductId) && (vv.UserName == "[email protected]")
select pp;
return View(query);
}
and I get the desired result:
But I don't want to write [email protected]
in the query, What If i have 1000+ users. I guess here I should pass the list of users who has voted the same products. I'm confused here. I would appreciate any help. Thanks
To break this down into its individual components
First you need to get the ID's of the products the current user has voted on
string UserId = User.Identity.GetUserName();
var userProducts = db.VoteLogs.Where(v => v.UserName == userId).Select(v => v.ProductId);
Then get all the other users who have also voted for one of those products
var likeUsers = db.VoteLogs.Where(v => userProducts.Contains(v.ProductId) && v.UserName != userId).Select(v => v.UserName);
Then get all other products that those users have voted on
var likeProducts = db.VoteLogs.Where(v => likeUsers.Contains(v.UserName)).Select(v => v.ProductId).Except(userProducts);
And finally return those products
return View(db.Products.Where(p => likeProducts.Contains(p.ID)));
Based on the table you have shown, this will return products 20
, 72
, 1187
and 1188
. If you were to add another row to your votes table with ProductId = 109
and UserName = "[email protected]"
then the results will be 19
, 20
, 30
, 72
, 1111
, 1187
and 1188
.
Note that since you have potentially thousands of users and products, this could return thousands of products to the view, so you may want to consider limiting the results, for example you might order the likeProducts
query by Vote
(highest) and take only the top #.