可以通过使用WHERE子句而不是FILTER来改进这个Neo4J Cypher查询吗?

时间:2013-09-03 05:12:51

标签: neo4j cypher

这是在Neo4J 2.0.0-M04上运行的。以下是数据和查询的链接http://console.neo4j.org/?id=yybtki

查询的目的是找到汤姆没有从读过类似书籍的人那里读过的书。

使用FILTER功能查询:

MATCH p1:Person-[:READS]->b1:Book<-[:READS]-p2:Person-[:READS]->b2:Book
WHERE p1.name = 'Tom' AND (p1-[:READS]->b1)
WITH COLLECT(b1) AS MyBooks, COLLECT(DISTINCT b2) AS OtherBooks
RETURN FILTER(x IN OtherBooks : NOT x IN MyBooks);

我已经设法使用FILTER函数成功运行查询,但是想知道在WHERE子句中是否有更好的方法。

尝试类似下面的内容不起作用。

MATCH p1:Person-[:READS]->b1:Book<-[:READS]-p2:Person-[:READS]->b2:Book
WHERE p1.name = 'Tom' AND NOT (p1-[:READS]->b1)
RETURN b2;

1 个答案:

答案 0 :(得分:2)

看起来你非常接近。诀窍是p1还不应该有读书b2而不是b1。

MATCH p1:Person-[:READS]->b1:Book<-[:READS]-p2:Person-[:READS]->b2:Book 
WHERE p1.name = 'Tom' AND NOT (p1-[:READS]->b2) 
RETURN b2

您可以通过按p1和p2的“相似性”排序书籍推荐来改进算法。一种非常简单的方法是使用共同阅读的书籍数量作为相似度的衡量标准:

MATCH sim=p1:Person-[:READS]->b1:Book<-[:READS]-p2:Person, p2-[:READS]->b2:Book 
WHERE p1.name = 'Tom' AND NOT (p1-[:READS]->b2) 
RETURN b2, count(sim) order by count(sim) desc

在你的例子中,有5个预订5的路径,只有一个预订3,所以假设第5册是更好的匹配。