Neo4j - 用户基于搜索历史的推荐

时间:2016-09-30 10:51:07

标签: neo4j cypher neo4j-cql

我有以下标签: -

  • 标签
  • 类型
  • 演员
  • 电影
  • 用户
  • UsersSerachHistory

我的应用用户有搜索栏,他们可以在其中键入和搜索任何内容,我将用户搜索的内容存储一段有限的时间以供将来推荐。基于用户搜索历史记录的推荐查询是什么?我是否需要创建搜索历史关系?在阅读了一些建议教程之后,我几乎无法编写以下查询 -

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

这不是一个完整的查询,而是一个粗略的想法,我不确定它是否正确?任何人都可以帮助我实现它吗?非常感谢!!

1 个答案:

答案 0 :(得分:3)

对于您当前的模型,我假设您可以执行以下建议:

  

找人喜欢你和他们一样的电影   就像你没看过那样

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

您可以应用相同类型的查询来查找具有相同类型的电影等。然后将结果合并。

有一篇很好的博客文章,其中包含许多针对Cypher推荐的示例查询:http://www.markhneedham.com/blog/2015/03/27/neo4j-generating-real-time-recommendations-with-cypher/

对于基于搜索的推荐,一个简单的解决方案是将搜索字符串拆分为元素,例如:

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

这将假设代表电影属性的所有节点都具有共同的value属性,因此:Tag(value):Year(value):Title(value)

这是一种基于搜索历史的常见推荐系统,您可以像时间轴一样对历史进行建模:

(user)-[:LAST_SEARCH]->(s)-[:PREV_SEARCH]->(s)..
(s)-[:HAS_KEYWORD]->(keyword)

enter image description here

然后,您将连续计算搜索历史之间的相似性作为后台作业。常见的算法是cosine similaritylikelihood function

然后,您可以根据与当前用户历史记录和其他用户历史记录的相似性找到潜在的类似搜索和返回的电影。

最后,当然,您可以结合所有推荐逻辑并计算最终得分。

根据你的评论:

  

用户搜索关键字可以是电影片名,演员姓名,   例如,如果它是标签名称,那么我想呈现   那些具有相同标签的电影

这是更多模式匹配,并不属于建议主题。