3

我试图了解 Neo4j 的有效使用模式,特别是参考高度节点。为了说明我在说什么,我的User节点具有我已建模为节点的属性。所以我的表中有一些关系,例如

(:User)-[:HAS_ATTRIB]->(:AgeCategory)

等等等等。问题是其中一些AgeCategory节点的度数非常高,在 100k 左右,查询如

MATCH (u:User)-->(:AgeCategory)<--(v:User), (u)-->(:FavoriteLanguage)<--(v)
WHERE u.uid = "AAA111" AND v.uid <> u.uid
RETURN v.uid

(匹配与 共享相同年龄类别和最喜欢语言的所有用户AAA111)非常非常慢,因为您必须为FavoriteLanguage链表中的每个元素运行一次AgeCategory链表(或者至少我是这样理解的)。

我认为这个查询需要几分钟才能解决我做错了什么这一事实很清楚,但我很好奇处理这样的查询的正确程序是什么。我应该单独从每个查询中提取匹配的用户并将它们与内存中的哈希进行比较吗?有没有办法在节点上的关系上放置索引?对于模式开始,这甚至是一个好主意吗?

4

1 回答 1

6

我的直觉是,首先检索给定节点 u 的两个端点(AgeCategory 和 FavoriteLanguage),然后在中间节点 v 中查询具有这两个固定端点的路径会更有效。

为了证明这一点,我创建了一个包含以下组件的测试图,

  1. 节点 u:User 与 u.uid = 'AAA111'
  2. 一个节点 c:AgeCategory
  3. 一个节点 l:FavoriteLanguage
  4. u和c的关系,u-[:HAS_AGE]->c
  5. u和l的关系,u-[:LIKE_LANGUAGE]->l
  6. 100,000 个节点 v,每个节点都与 ndoe u 共享相同的 c:AgeCategory 和 l:FavoriteLanguage,即每个 v 连接到 l 和 c,v-[:HAS_AGE]->c,v-[:LIKE_LANGUAGE]-> l

我运行以下查询 10 次,平均运行时间为 10500 毫秒。

Match l:FavoriteLanguage<-[:LIKE_LANGUAGE]-u:User-[:HAS_AGE]->c:AgeCategory
Where u.uid = 'AAA111'
With l,c
Match l<-[:LIKE_LANGUAGE]-v:User-[:HAS_AGE]->c 
Where v.uid <> 'AAA111'
Return v.uid

对于 10,000 个 v 节点,此查询大约需要 2000 毫秒,您的查询大约需要 27000 毫秒。

使用 100,000 个 v 节点,此查询大约需要 10500 毫秒,对于您的原始查询来说似乎需要很长时间。

所以你可以试试这个查询,看看它是否可以提高你的图表的性能。

于 2013-08-27T18:55:07.440 回答