Reputation: 5344
I have Following labels :-
My app user has search bar where they can type and search anything , I am storing users searched contents for a limited period of time for future recommendations.What will be the query for Recommendation based on Users search history? Should I need to create relationship of search history? After gone through some tutorial for recommendations , I am little bit able to write following query -
MATCH (m:Movie)<-[:LIKE]-(p:Person {personId : 1})
OPTIONAL MATCH (t:Tag)
WITH collect(distinct t.tagName) as c1
OPTIONAL MATCH (g:Genre)
WITH collect(distinct g.name) + c1 as c2
OPTIONAL MATCH (l:Language)
WITH collect(distinct l.languageName) + c2 as c3
RETURN c3
It is not a complete query but a rough idea and am not sure is it correct way? Can anybody help me to achieve it? Thanks much!!
Upvotes: 0
Views: 275
Reputation: 20185
Well with your current model, I assume you can do recommendations like :
Find people liking the same movies as you, what other movies do they like that you didn't watched yet
MATCH (p:Person {personId: 1})-[:LIKE]->(movie)<-[:LIKE]-(other)
WITH distinct other, p
MATCH (other)-[:LIKE]->(reco)
WHERE NOT (p)-[:LIKE]->(reco)
RETURN reco, count(*) as score
ORDER BY score DESC
You can apply the same kind of queries for finding movies having the same genres, etc.. and combine the results afterwards.
There is a good blog post with lot of example queries for recommendations with Cypher : http://www.markhneedham.com/blog/2015/03/27/neo4j-generating-real-time-recommendations-with-cypher/
For recommendations based on search, an easy solution is to split the search string into elements, for example :
WITH split("action movie with arnold in 1997", " ") AS elements
MATCH (m:Movie)<-[r]-(object)
WHERE object.value IN elements
RETURN m, count(*) as score
This would assume that all nodes representing a property of a movie would have a common value
property, so :Tag(value)
, :Year(value)
, :Title(value)
This is kind of basic, in common recommender systems based on search history, you would model the history like a timeline :
(user)-[:LAST_SEARCH]->(s)-[:PREV_SEARCH]->(s)..
(s)-[:HAS_KEYWORD]->(keyword)
Then you will compute the similarity between search histories continuously as a background job. A common algorithm is cosine similarity or likelihood function
You then can find potential similar searches and returned movies based on the similarity with the current user history and other user histories.
Lastly of course, you can combine all of the recommendation logic and compute a final score.
And based on your comment :
Users search keyword could be anything like movie title , actor name , tag etc.So for example if it is a tag name then I want to present those movies having the same tag
This is more pattern matching and doesn't really fall in the topic of recommendations.
Upvotes: 3