在这里,我试图找到所有跟随并跟随某个组G
成员的Twitter用户:
MATCH (x:User)-[:FOLLOWS]->(t:User)-[:FOLLOWS]->(y:User)
WHERE (x.screen_name IN {{G_SCREEN_NAMES}} OR x.id IN {{G_IDS}})
AND (y.screen_name IN {{G_SCREEN_NAMES}} OR y.id IN {{G_IDS}})
RETURN t.id
但是对于组G
我有时会有他们的屏幕名称,有时会有他们的ID,因此上面是OR
子句。不幸的是,这个查询已经运行很长时间,并且似乎无法返回。
我在id
和screen_name
上都有索引和约束:
Indexes
ON :User(screen_name) ONLINE (for uniqueness constraint)
ON :User(id) ONLINE (for uniqueness constraint)
Constraints
ON (user:User) ASSERT user.screen_name IS UNIQUE
ON (user:User) ASSERT user.id IS UNIQUE
如果我摆脱了OR子句(例如,如果我碰巧拥有G组的所有screen_names或所有id),那么查询运行得非常快。
我在Mac上使用neo4j-community-2.1.3。我的图表有286039个节点,所有节点都有User
标签。
想要改进这个吗?否则,我必须将其分为4个查询以获得所有可能的成员组合。这确实更成问题,因为我真的想跟踪用户
我创建了一个与此相关的问题:https://github.com/neo4j/neo4j/issues/2834
我最终使用
MATCH (x:User) WHERE x.screen_name IN ["apple","banana","coconut"]
WITH collect(id(x)) as x_ids
MATCH (x:User) WHERE x.id in [12345,98765]
WITH x_ids+collect(id(x)) as x_ids
MATCH (y:User) WHERE y.screen_name IN ["apple","banana","coconut"]
WITH x_ids,collect(id(y)) as y_ids
MATCH (y:User) WHERE y.id in [12345,98765]
WITH x_ids,y_ids+collect(id(y)) as y_ids
MATCH (x:User)-[:FOLLOWS]->(t:User)-[:FOLLOWS]->(y:User)
WHERE id(x) in x_ids AND id(y) in y_ids
RETURN count(*) as c, t.screen_name,t.id
ORDER BY c DESC
LIMIT 1000
但这基本上代表了一个黑客来绕过neo4j并没有使用它可能的指数。
答案 0 :(得分:3)
我认为由于OR
条件,查询没有使用索引,您可以通过在查询前添加PROFILE
来验证并在neo4j-shell中运行它。
如果没有索引使用的概念,您可以将查询分成两部分。第一个获取用户ID的组合列表,而不是OR,我们对两个查询(每个使用索引查找)执行UNION:
MATCH (x:User) WHERE x.screen_name in {G_SCREEN_NAMES} RETURN id(x) as ids UNION
MATCH (x:User) WHERE x.id in {G_IDS} RETURN id(x) as ids
在客户端,使用节点ID列表作为下一个查询的参数:
MATCH (x:User)-[:FOLLOWS]->(t)-[:FOLLOWS]->(y)
WHERE id(x) in {ids} AND id(y) in {ids}
RETURN t.id
我故意删除了t
和y
的标签,并假设您只能关注User
而没有其他类型的节点。这将删除不必要的标签检查。
答案 1 :(得分:2)
JnBrymn,
这个查询怎么样?
MATCH (x:User)
WHERE x.screen_name IN {{G_SCREEN_NAMES}} OR x.id IN {{G_IDS}}
WITH x
MATCH (x)-[:FOLLOWS]->(t:User)
WITH t
MATCH (t)-[:FOLLOWS]->(y:User)
WHERE y.screen_name IN {{G_SCREEN_NAMES}} OR y.id IN {{G_IDS}}
RETURN t.id
恩典与和平,
吉姆