如何为每个节点返回按关系排序的所有邻居节点

时间:2017-06-25 15:31:09

标签: neo4j cypher

我希望你能帮助我。我想要计算每个节点的所有邻居按关系类型分配。 例如,如果我得到这个图:

enter image description here

我想获得以下节点165:

id     AnzTaxi    AnzBus   AnzSchiff
165    2          2        0

我做了这个查询,但似乎neo4j将我的“匹配”连接为AND,所以它只会列出节点,每个类型至少有一个关系。

MATCH (Station)-[:TAXI]-(b) 
MATCH (Station)-[:BUS]-(c) 
MATCH (Station)-[:SCHIFF]-(d)
RETURN Station.id, COUNT(DISTINCT b) AS AnzTaxi, 
COUNT(DISTINCT c) AS AnzBus, COUNT(DISTINCT d) AS 
AnzSchiff 
ORDER BY COUNT(DISTINCT b) DESC;

非常感谢提前!

3 个答案:

答案 0 :(得分:4)

您应该使用OPTIONAL MATCH而不是简单的MATCH。文档说:

  

OPTIONAL MATCH 子句用于搜索所描述的模式   在其中,使用空值来删除模式的缺失部分。

试一试:

OPTIONAL MATCH (Station)-[:TAXI]-(b) 
OPTIONAL MATCH (Station)-[:BUS]-(c) 
OPTIONAL MATCH (Station)-[:SCHIFF]-(d)
RETURN Station.id, COUNT(DISTINCT b) AS AnzTaxi, 
COUNT(DISTINCT c) AS AnzBus, COUNT(DISTINCT d) AS 
AnzSchiff 
ORDER BY COUNT(DISTINCT b) DESC;

答案 1 :(得分:3)

另一种方法是根本不扩展,并使用关系度(存储在节点本身上)来获得所需的计数。

MATCH (Station)
RETURN Station.id, 
 size((Station)<-[:BUS]-()) AS AnzBus, 
 size((Station)<-[:TAXI]-()) AS AnzTaxi, 
 size((Station)<-[:SCHIFF]-()) AS AnzSchiff 
ORDER BY AnzBus DESC;

请注意,这会计算关系而不是节点,这假设(从您的示例中)图中的每个:BUS,:TAXI和:SCHIFF关系在每个连接的节点之间都有传入和传出关系。

虽然如果是这种情况,最好只使用节点之间的一种关系对其进行建模,并将其视为双向而不是不必要地加倍关系(如果你确实进行了更改,则需要从关系中删除方向在我的查询中。)

如果你的模型不能像这样工作,并且关系可以单向,但不能被回报(因此可以有一个传出:与节点的BUS关系,但没有传入:来自同一节点的BUS关系) ,那么这个答案是行不通的,你应该选择其中一个。

答案 2 :(得分:2)

另一种方法是一次匹配所有邻居节点,而不是三个单独的可选语句。这样,如果没有结果,那么你就会知道没有通过 TAXI BUS SCHIFF 连接的邻居。然后,您可以使用0 0x5555555a6633 testing::Cardinality::ConservativeUpperBound() const () (??:??) 1 0x5555555a1a13 testing::internal::ExpectationBase::CheckActionCountIfNotDone() const () (??:??) 2 0x555555563f98 testing::internal::TypedExpectation<void (int)>::ShouldHandleArguments(std::tuple<int> const&) const(this=0x5555557f58a0, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1100) 3 0x55555556397d testing::internal::FunctionMockerBase<void (int)>::FindMatchingExpectationLocked(std::tuple<int> const&) const(this=0x7fffffffde38, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1723) 4 0x555555563578 testing::internal::FunctionMockerBase<void (int)>::UntypedFindMatchingExpectation(void const*, void const**, bool*, std::ostream*, std::ostream*)(this=0x7fffffffde38, untyped_args=0x7fffde7fbe14, untyped_action=0x7fffde7fb7d0, is_excessive=0x7fffde7fb7c7, what=0x7fffde7fb900, why=0x7fffde7fba90) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1687) 5 0x5555555a265e testing::internal::UntypedFunctionMockerBase::UntypedInvokeWith(void const*) () (??:??) 6 0x55555555fcba testing::internal::FunctionMockerBase<void (int)>::InvokeWith(std::tuple<int> const&)(this=0x7fffffffde38, args=std::tuple containing = {...}) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-spec-builders.h:1585) 7 0x55555555f16c testing::internal::FunctionMocker<void (int)>::Invoke(int)(this=0x7fffffffde38, a1=1) (../googletest-release-1.8.0/googlemock/include/gmock/gmock-generated-function-mockers.h:101) 8 0x55555555ecb6 DummyMock::SomeMethod(this=0x7fffffffde30, gmock_a1=1) (/home/jos/Programming/ThreadSafeGMock/main.cpp:16) 9 0x55555555d31e SomeTest_Test100_Test::<lambda()>::operator()(void) const(__closure=0x5555557f5478) (/home/jos/Programming/ThreadSafeGMock/main.cpp:36) 10 0x55555555de98 std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>)(this=0x5555557f5478) (/usr/include/c++/6/functional:1391) 11 0x55555555de22 std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()>::operator()(void)(this=0x5555557f5478) (/usr/include/c++/6/functional:1380) 12 0x55555555ddf2 std::thread::_State_impl<std::_Bind_simple<SomeTest_Test100_Test::TestBody()::<lambda()>()> >::_M_run(void)(this=0x5555557f5470) (/usr/include/c++/6/thread:197) 13 0x7ffff7b0a83f ??() (/usr/lib/x86_64-linux-gnu/libstdc++.so.6:??) 14 0x7ffff76216da start_thread(arg=0x7fffde7fc700) (pthread_create.c:456) 15 0x7ffff735b17f clone() (../sysdeps/unix/sysv/linux/x86_64/clone.S:105) 语句在事后将它们分开,并使用CASE将它们聚合起来。

SUM