2

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

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

使用 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;
4

1 回答 1

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 册有 2 条路径,而第 3 册只有一条路径,因此假设第 5 册是更好的匹配。

于 2013-09-03T06:52:44.103 回答