2

我正在尝试构建 Facebook 上人们喜欢的不同实体的图表,以创建一个基本的跨域推荐引擎。

我有不同实体(电影、书籍、音乐等)的数据。为每个项目创建节点,其属性为项目名称(电影名称、书籍等)和项目实体类型(电影、书籍等)。任何两个节点之间都有称为“亲和性”的关系。这种关系还有一个“强度”属性,等于没有。喜欢这两个项目的人。

我使用 FB 用户连接这些节点。FB 用户也是图中的节点,其属性为人名,类型为人。这些节点和项目节点之间的关系称为“喜欢”。现在,如果一个人喜欢一部电影,我想通过遍历图向他推荐书籍或音乐。这是我试图遍历图表的密码查询:

START root = node(<LIKED_MOVIE_NODE_ID>)
MATCH p = root-[rel1:affinity*..3]-(movies)<-[rel2:likes]-(persons)-[rel3:likes]->(books)
WHERE HAS(movies.type) and movies.type = "movies" and HAS(persons.type) and persons.type = "person" and HAS(books.type) and books.type = "books"
RETURN books

这运行非常缓慢,有时需要长达 500 秒。我有大约 13000 部电影、2000 本书和 3000 个音乐节点。连接他们的是16000人。总共有大约 300,000 个关系。

我的问题是:

  1. 难道我做错了什么?有一个更好的方法吗?我是neo4j的新手。我已经尝试了一些调整 neo4j graphDB 的技术。我已将最小堆大小增加到 4 GB,并在具有 32 GB RAM 的 8 核机器上运行它。

  2. 我想知道关系 rel1 的强度以及 rel2 和 rel3 的数量。Rel1 具有属性强度。我查不出来,

请告知,因为我即将放弃 neo4j 并返回 SQL。至少它有效。:(

Regds,帕里托什

4

1 回答 1

1

密码很慢。与遍历和核心 API ( http://java.dzone.com/articles/get-full-neo4j-power-using )相比,实际上非常慢

也就是说,您可以尝试通过将 Match 拆分为不同的 WITH 子句来限制 neo4j 进程的节点数量。例如,根据您的用例,您可以将 root-[rel1:affinity*..3]-(movies) 放在单独的子句中,并过滤掉不同的电影。否则 neo4j 将处理通向电影的所有路径组合。

PS:

WHERE HAS(movies.type) and movies.type = "movies" and HAS(persons.type) and persons.type = "person" and HAS(books.type) and books.type = "books"

可以改写为

WHERE movies.type! = "movies" and persons.type! = "person" and books.type! = "books"

或者,如果您使用的是 neo4j 2.0.0M4,您可以跳过 HAS()

于 2013-08-30T10:29:01.163 回答