这是在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;
答案 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册是更好的匹配。