Cypher /关于基本关系的效率

时间:2014-10-19 07:26:59

标签: neo4j cypher graph-databases

使用Neo4j 2.X和Cypher,我想直接或通过朋友查询我认识的所有Users

我希望这样的事情:

MATCH (me:User("123"))-[:KNOWS*1..2]-(friend)  //does not work of course

我考虑shortestPath功能,但是它不会太贵吗?

此外,如果我有这个问题:

MATCH (a)-[:SOME_REL]->(b)<-[:OWNS_BY]-(me:User("123"))   // would load the whole in memory before filtering by knowledge !
WITH shortestPath((me)-[:KNOWS*..2]-(friend)) as path
WHERE path.length <= 2

OR

MATCH (a)-[:SOME_REL]->(b)<-[:OWNS_BY]-(me:User("123"))   // would load the whole in memory before filtering by knowledge !
MATCH path = shortestPath((me)-[:KNOWS*..2]-(friend))
WHERE path.length <= 2

难道不是更多(可能在大图的情况下也是如此?)昂贵吗?

事实上,如果有效的话会更好:

MATCH (a)-[:SOME_REL]->(b)<-[:OWNS_BY]-(me:User("123"))-[:KNOWS*1..2]-(friend)

仅在内存中加载适当的路径。

我也可以使用这样的替代方案:

OPTIONAL MATCH (a)-[:SOME_REL]->(b)<-[:OWNS_BY]-(me:User("123"))-[:KNOWS]-(friend)
OPTIONAL MATCH (a)-[:SOME_REL]->(b)<-[:OWNS_BY]-(me:User("123"))-[:KNOWS]-()-[:KNOWS]-(friend)

但想象一下,如果我想要三度分离(知识)...查询将是非常多余的。

是否有良好的语法可以提高查询效率?
我该怎么用?

1 个答案:

答案 0 :(得分:3)

我不确定我完全理解,我认为你的第一个查询会有效吗?

MATCH (me:User{userId:123})-[:KNOWS*1..2]-(friend:User)
WHERE me <> friend
RETURN friend

很难知道要为其他查询写什么,因为OWNS_BY和SOME_REL组件似乎与朋友组件的朋友无关,如果您可以将查询的两半与具体示例联系起来我可以解释最佳方法。

一些关键指标是你应该

  1. 使用您认为与最小节点集匹配的内容开始查询(以限制必须完成的工作)。
  2. 确保所有查询组件都使用标签和关系类型。
  3. 在将要在查找中使用的属性上创建索引。
  4. 优秀的查询优化资源是Wes Freeman's Pragmatic Optimisation

    图表的大小不需要使查询更加昂贵,因为您将主要处理可能具有更多固定大小边界的子图。当然,如果您的查询需要跨越整个图表,那么大小将成为速度问题!