提升Neo4j的推荐结果

时间:2015-10-12 17:23:52

标签: neo4j cypher union social-networking recommendation-engine

我尝试使用 Neo4j 实施推荐算法,这类似于此page上的实现。

现在我有一个简单的社交示例,其中用户可以:

  • 关注其他用户
  • 游戏
  • 在一个国家/地区

这个想法是根据其他用户是否是朋友的朋友,玩同一个游戏,住在同一个国家和/或跟踪有问题的用户来制作朋友建议算法。

除了后者之外,使用上面的页面中的示例很容易实现,如下所示:

MATCH (origin)-[r1:FOLLOWS|PLAYS|LIVES_IN]-(c)-[r2:FOLLOWS|PLAYS|LIVES_IN]-(candidate)
WHERE type(r1)=type(r2) AND NOT (source)-[:FOLLOWS]->(candidate)  
RETURN candidate, SUM(ROUND(r2.weight) AS boost
ORDER BY boost DESC LIMIT 10

然而,一次完成整个事情的唯一可行方法是与另一个查询联合并处理结果。这些方面的东西:

THE_QUERY_ABOVE

UNION

MATCH (origin)<-[r:FOLLOWS]-(candidate)
RETURN candidate, r.weight as boost

WITH candidate, boost
RETURN DISTINCT candidate, SUM(boost)
ORDER BY boost DESC LIMIT 10

但据我所知,Cypher无法对UNION结果进行后期处理......

因此,我的问题是:这可以在单个查询中实现吗?以及如何?

如果是,是否有可能的解决方案,我不必在关系中指定权重,以避免在我想改变优先级时改变所有关系?

干杯!

2 个答案:

答案 0 :(得分:0)

[EDITED]

OPTIONAL MATCH (origin)-[r1:FOLLOWS|PLAYS|LIVES_IN]-(c)-[r2:FOLLOWS|PLAYS|LIVES_IN]-(candidate)
WHERE type(r1)=type(r2) AND NOT (origin)-[:FOLLOWS]->(candidate)
WITH origin,candidate,(
  CASE
  WHEN candidate IS NOT NULL THEN [{ candidate: candidate, boost: SUM(ROUND(r2.weight))}]
  ELSE NULL END ) AS res1
OPTIONAL MATCH (candidate)-[r3:FOLLOWS]->(origin)
WITH (
  CASE
  WHEN candidate IS NOT NULL THEN [{ candidate: candidate, boost: SUM(ROUND(r3.weight))}]
  ELSE NULL END )+ res1 AS res2
UNWIND res2 AS result
RETURN result.candidate AS candidate, SUM(result.boost) AS boost
ORDER BY boost DESC 
LIMIT 10;

这对你有用吗? 如果这不起作用,您可以share a console使用示例数据吗?

它使用共享相同OPTIONAL MATCHorigin个节点的2个candidate子句。每个OPTIONAL MATCH子句负责处理您的OR个案例,将该案例的结果放在地图集合中(如果匹配失败,则为NULL)。接近结束时,集合(包含具有相同结构的映射)被组合并展开为单独的行。最后,具有相同candidate值的行将boost值相加,并返回前10个结果(按增加值)。

答案 1 :(得分:0)

您可以使用&#34;可选匹配&#34;