密码查询中的独立匹配

时间:2017-03-01 16:47:08

标签: neo4j cypher

我有一个包含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查询交叉加入的问题?
  • 浮动师很难看。

第二个是我可以忍受的东西,但第一个似乎效率低下;是否有更好的方式来表达这个想法?

1 个答案:

答案 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)