如何在搜索两种不同关系类型的 Neo4J 3.x 中构建 Cypher / APOC 查询?
How to build a Cypher / APOC query in Neo4J 3.x which searches on two different relationship types?
目前我使用以下 Cypher / APOC 查询通过某个 属性 (user
id) 搜索关系类型 TO
:
CALL apoc.index.relationships('TO','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
ETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight;
我希望不仅可以搜索索引 TO
,还可以搜索索引 AT
(AT
类型的关系),以便生成 rel
参数同时包含 TO
和 AT
关系。
我想它会像添加一个 OR
运算符一样简单,如下所示:
CALL apoc.index.relationships('TO','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') OR
apoc.index.relationships('AT','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight;
但是没用...
也许我可以做一些事情,我可以从这两个 apoc
中得到 rel
,然后简单地将它们合并为一个 rel
,但我真的不明白怎么做...或者我没有看到更简单的方法?
UNION 子句的用途:
CALL apoc.index.relationships('TO','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight
UNION
CALL apoc.index.relationships('AT','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight
你可以用 run cypher fragment:
WITH '16c01100-aa92-11e3-a3f6-35e25c9775ff' as userId
CALL apoc.cypher.run("
CALL apoc.index.relationships('TO','user:' + $id) YIELD rel
RETURN rel
", {id: userId}) YIELD value
WITH userId, collect(value.rel) as r1
CALL apoc.cypher.run("
CALL apoc.index.relationships('AT','user:' + $id) YIELD rel
RETURN rel
", {id: userId}) YIELD value
WITH r1, collect(value.rel) as r2
UNWIND (r1 + r2) as rel
WITH rel, nodeStart(rel) as start, nodeEnd(rel) as end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight;
目前我使用以下 Cypher / APOC 查询通过某个 属性 (user
id) 搜索关系类型 TO
:
CALL apoc.index.relationships('TO','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
ETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight;
我希望不仅可以搜索索引 TO
,还可以搜索索引 AT
(AT
类型的关系),以便生成 rel
参数同时包含 TO
和 AT
关系。
我想它会像添加一个 OR
运算符一样简单,如下所示:
CALL apoc.index.relationships('TO','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') OR
apoc.index.relationships('AT','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight;
但是没用...
也许我可以做一些事情,我可以从这两个 apoc
中得到 rel
,然后简单地将它们合并为一个 rel
,但我真的不明白怎么做...或者我没有看到更简单的方法?
UNION 子句的用途:
CALL apoc.index.relationships('TO','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight
UNION
CALL apoc.index.relationships('AT','user:16c01100-aa92-11e3-a3f6-35e25c9775ff') YIELD rel, start, end
WITH DISTINCT rel, start, end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight
你可以用 run cypher fragment:
WITH '16c01100-aa92-11e3-a3f6-35e25c9775ff' as userId
CALL apoc.cypher.run("
CALL apoc.index.relationships('TO','user:' + $id) YIELD rel
RETURN rel
", {id: userId}) YIELD value
WITH userId, collect(value.rel) as r1
CALL apoc.cypher.run("
CALL apoc.index.relationships('AT','user:' + $id) YIELD rel
RETURN rel
", {id: userId}) YIELD value
WITH r1, collect(value.rel) as r2
UNWIND (r1 + r2) as rel
WITH rel, nodeStart(rel) as start, nodeEnd(rel) as end
MATCH (ctx:Context)
WHERE rel.context = ctx.uid
RETURN DISTINCT start.uid AS source_id,
start.name AS source_name,
end.uid AS target_id,
end.name AS target_name,
rel.uid AS edge_id,
ctx.name AS context_name,
rel.statement AS statement_id,
rel.weight AS weight;