我有一个包含User,Content和Topic节点的Neo4j数据库。我想计算给定用户对给定主题消耗的内容比例。
MATCH (u:User)-[:CONSUMED]->(c:Content)<-[:CONTAINS]-(t:Topic)
WHERE ID(u) = 11158 AND ID(t) = 19853
MATCH (c1:Content)<-[:CONTAINS]-(z)
RETURN toFloat(COUNT(DISTINCT(c))) / toFloat(COUNT(DISTINCT(c1)))
有两件事让我感到非常难看:
COUNT(DISTINCT())
是否可以解决两个MATCH
查询交叉加入的问题?第二个是我可以忍受的东西,但第一个似乎效率低下;是否有更好的方式来表达这个想法?
答案 0 :(得分:1)
内容计数应返回用户消费的内容数量,除非他们多次使用相同的内容。
如果您的模型允许,您可以只获取出站CONTAINS
关系的大小,而不是匹配主题中的所有内容。
MATCH (u:User)-[:CONSUMED]->(c:Content)<-[:CONTAINS]-(t:Topic)
WHERE ID(u) = 11158 AND ID(t) = 19853
RETURN toFloat(count(distinct c))/ size((t)-[:CONTAINS]->()) as proportion
您的原始查询返回用户内容主题匹配数量x主题内容匹配数量的笛卡尔积。作为上述的替代方法,您可以重写这样的原始查询。这将获取用户为主题消耗的内容,进行聚合,然后将主题和结果计数传递给查询中的下一个子句。这将有效,但使用size((t)-[:CONTAINS]->())
会更有效率。
MATCH (u:User)-[:CONSUMED]->(c:Content)<-[:CONTAINS]-(t:Topic)
WHERE ID(u) = 11158 AND ID(t) = 19853
WITH t, count(distinct c ) as distinct_content
MATCH (t)-[:CONTAINS]->(c1:Content)
RETURN toFloat(distinct_content) / count(c1)