2

我创建了一个测试数据集,类似于一些具有以下结构的客户端数据:

   *1                100k              *3..30
[:author]-------->  person  <---------[:member]
    |                 |                  |
    |               *2..8                |
    |              [:topic]              |
    |                 |                  |
    |    *3..8        V        *3..8     |
article-[:topic]->  topic  <-[:topic]- project
    1m                1k                 20k

这些数字意味着例如我有 100 万篇文章,每篇文章都有一位作者,每篇文章有 3 到 8 个 rel 到 1000 个主题之一。

现在我有两个问题:

第一:这种布局有意义吗?主题成为超级节点 - 将它们作为节点上的属性会更好吗?

其次,我发现查询的巨大性能差异取决于我如何表达它。我们的想法是找到一起参与过一个项目的人,并且对某个主题有共同的兴趣:

查询1

match 
    n:person<-[:member]-p:project-[:member]->m, 
    n-[:topic]->t,
    m-[:topic]->t 
where 
    n.name='person1215' and 
    n<>m 
return 
    m,t;

这在1500ms-9000ms范围内返回。

query2要快得多:

match 
    n:person<-[:member]-p:project-[:member]->m, 
    n-[:topic]->t1, 
    m-[:topic]->t2  
where 
    n.name='person1250' and 
    n<>m and 
    t1=t2 
return 
    t1,m;

中返回200ms-400ms

第二:为什么 query2 这么快? 仅查看该查询会如何看待这一点?

query1的探查器输出:

ColumnFilter(symKeys=["n", "t", "m", "  UNNAMED14", "p", "  UNNAMED51", "  UNNAMED35", "  UNNAMED66"], returnItemNames=["m", "t"], _rows=3, _db_hits=0)
Filter(pred="((NOT(n == m) AND hasLabel(p: project)) AND hasLabel(p: project))", _rows=3, _db_hits=0)
  PatternMatch(g="(p)-['  UNNAMED35']-(m),(p)-['  UNNAMED14']-(n),(m)-['  UNNAMED66']-(t),(n)-['  UNNAMED51']-(t)", _rows=3, _db_hits=0)
    SchemaIndex(identifier="n", _db_hits=0, _rows=1, label="person", query="Literal(person1215)", property="name")

对于query2

ColumnFilter(symKeys=["n", "  UNNAMED67", "m", "  UNNAMED14", "t2", "p", "  UNNAMED51", "t1", "  UNNAMED35"], returnItemNames=["t1", "m"], _rows=2, _db_hits=0)
Filter(pred="(((NOT(n == m) AND t1 == t2) AND hasLabel(p: project)) AND hasLabel(p: project))", _rows=2, _db_hits=0)
  PatternMatch(g="(p)-['  UNNAMED35']-(m),(p)-['  UNNAMED14']-(n),(m)-['  UNNAMED67']-(t2),(n)-['  UNNAMED51']-(t1)", _rows=2, _db_hits=0)
    SchemaIndex(identifier="n", _db_hits=0, _rows=1, label="person", query="Literal(person1250)", property="name")

非常感谢,

约尔格

4

1 回答 1

1

Joerg,可能是您在模式匹配器选择中发现了一个错误,这些查询实际上应该使用遍历匹配器。

如果您提出 GitHub 问题,我们将跟进该问题。非常感谢!!

对于“超级节点”主题,使用不太通用的关系类型可能是有意义的,它允许对节点的关系进行子组织(在内存中)。例如:project_topic, article_topic, :interest_topic. 你能试试这个吗?

那么您的查询将是:

match 
    n:person<-[:member]-p:project-[:member]->m, 
    n-[:interest_topic]->t,
    m-[:interest_topic]->t 
where 
    n.name='person1215' and 
    n<>m 
return 
    m,t;

顺便提一句。由于节点唯一性约束m实际上不应与 n 相同,您在查询中看到了吗?

如果你离开第二个标签检查会发生什么也会很有趣(:project只是好奇)。

另外,请注意 2.0 尚未进行性能优化。对于专门的人员查找,它会更快更接近 GA。

于 2013-08-09T01:49:17.120 回答