拥有流动的数据模型:
(Phone{phoneNumber})-[:CALL]-(Phone{phoneNumber})
(Person{personId})-[:KEEP]-(Phone{personId})
(Case{caseId})-[:INVOLVE]-(Person{personId})
所有这三个都使用双向关系。并在phoneNumber / personId / caseId上创建了索引。
用户可以输入一个或多个字符串,可能表示为phoneNumber / caseId / personId查询他们的关系(不考虑方向和关系深度可以是1到4)。
这是密码查询:
match p = n-[r*1..4]-m
with n,m,p
where (n.phoneNumber in ["xxx","yyy"]
or n.caseSjNo in ["xxx","yyy"]
or n.identificationNumber in ["xxx","yyy"])
and (m.phoneNumber in ["xxx","yyy"]
or m.caseSjNo in ["xxx","yyy"]
or m.identificationNumber in ["xxx","yyy"])
and n <> m
return p limit 1000
我在shell控制台中分析了这个查询字符串。在neo4j db中有10,000个节点,我发现 Dbhits 非常棒。这是结果(深度= 1和深度= 4):
neo4j-sh (?)$ profile match p = n-[r*1..1]-m with n,m,p where (n.phoneNumber in ["XXX","YYY"] or n.caseSjNo in ["XXX","YYY"] or n.identificationNumber in ["XXX","YYY"]) and (m.phoneNumber in ["XXX","YYY"] or m.caseSjNo in ["XXX","YYY"] or m.identificationNumber in ["XXX","YYY"]) and n <> m return p limit 1000;
==> +---+
==> | p |
==> +---+
==> +---+
==> 0 row
==>
==> ColumnFilter(0)
==> |
==> +Slice
==> |
==> +Filter
==> |
==> +ColumnFilter(1)
==> |
==> +ExtractPath
==> |
==> +TraversalMatcher
==>
==> +------------------+-------+--------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
==> | Operator | Rows | DbHits | Identifiers | Other |
==> +------------------+-------+--------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
==> | ColumnFilter(0) | 0 | 0 | | keep columns p |
==> | Slice | 0 | 0 | | { AUTOINT12} |
==> | Filter | 0 | 480776 | | ((((any(-_-INNER-_- in Collection(List({ AUTOSTRING0}, { AUTOSTRING1})) where Property(n,phoneNumber(3)) == -_-INNER-_-) OR any(-_-INNER-_- in Collection(List({ AUTOSTRING2}, { AUTOSTRING3})) where Property(n,caseSjNo(0)) == -_-INNER-_-)) OR any(-_-INNER-_- in Collection(List({ AUTOSTRING4}, { AUTOSTRING5})) where Property(n,identificationNumber(2)) == -_-INNER-_-)) AND ((any(-_-INNER-_- in Collection(List({ AUTOSTRING6}, { AUTOSTRING7})) where Property(m,phoneNumber(3)) == -_-INNER-_-) OR any(-_-INNER-_- in Collection(List({ AUTOSTRING8}, { AUTOSTRING9})) where Property(m,caseSjNo(0)) == -_-INNER-_-)) OR any(-_-INNER-_- in Collection(List({ AUTOSTRING10}, { AUTOSTRING11})) where Property(m,identificationNumber(2)) == -_-INNER-_-))) AND NOT(n == m)) |
==> | ColumnFilter(1) | 20034 | 0 | | keep columns n, m, p |
==> | ExtractPath | 20034 | 0 | p | |
==> | TraversalMatcher | 20034 | 50152 | | m, UNNAMED11, m, r |
==> +------------------+-------+--------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
==>
==> Total database accesses: 530928
------------------------------------------------------
------------------------------------------------------
neo4j-sh (?)$ profile match p = n-[r*1..4]-m with n,m,p where (n.phoneNumber in ["XXX","YYY"] or n.caseSjNo in ["XXX","YYY"] or n.identificationNumber in ["XXX","YYY"]) and (m.phoneNumber in ["XXX","YYY"] or m.caseSjNo in ["XXX","YYY"] or m.identificationNumber in ["XXX","YYY"]) and n <> m return p limit 1000 ;
==> +---+
==> | p |
==> +---+
==> +---+
==> 0 row
==>
==> ColumnFilter(0)
==> |
==> +Slice
==> |
==> +Filter
==> |
==> +ColumnFilter(1)
==> |
==> +ExtractPath
==> |
==> +TraversalMatcher
==>
==> +------------------+---------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
==> | Operator | Rows | DbHits | Identifiers | Other |
==> +------------------+---------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
==> | ColumnFilter(0) | 0 | 0 | | keep columns p |
==> | Slice | 0 | 0 | | { AUTOINT12} |
==> | Filter | 0 | 120244220 | | ((((any(-_-INNER-_- in Collection(List({ AUTOSTRING0}, { AUTOSTRING1})) where Property(n,phoneNumber(3)) == -_-INNER-_-) OR any(-_-INNER-_- in Collection(List({ AUTOSTRING2}, { AUTOSTRING3})) where Property(n,caseSjNo(0)) == -_-INNER-_-)) OR any(-_-INNER-_- in Collection(List({ AUTOSTRING4}, { AUTOSTRING5})) where Property(n,identificationNumber(2)) == -_-INNER-_-)) AND ((any(-_-INNER-_- in Collection(List({ AUTOSTRING6}, { AUTOSTRING7})) where Property(m,phoneNumber(3)) == -_-INNER-_-) OR any(-_-INNER-_- in Collection(List({ AUTOSTRING8}, { AUTOSTRING9})) where Property(m,caseSjNo(0)) == -_-INNER-_-)) OR any(-_-INNER-_- in Collection(List({ AUTOSTRING10}, { AUTOSTRING11})) where Property(m,identificationNumber(2)) == -_-INNER-_-))) AND NOT(n == m)) |
==> | ColumnFilter(1) | 5010178 | 0 | | keep columns n, m, p |
==> | ExtractPath | 5010178 | 0 | p | |
==> | TraversalMatcher | 5010178 | 20070774 | | m, UNNAMED11, m, r |
==> +------------------+---------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
==>
==> Total database accesses: 140314994
虽然结果出来了,但这花了太长时间。任何查询优化的提示。
更新 在db中有1,000,000(1M)个节点时,发生内存不足错误。
答案 0 :(得分:4)
为什么首先使用双向关系?在Neo4j中,您始终可以双向导航。
请参阅:
create index on :Entity(id);
match (n:Entity),(m:Entity)
where n.id in ["xxx","yyy"] and m.id in ["xxx","yyy"] and n<>m
match p = (n)-[r*1..4]-(m)
return p
limit 1000
match p = (n:Person)-[r*1..4]-(m:Case)
where n.identificationNumber in ["xxx","yyy"] and m.caseSjNo in ["xxx","yyy"]
return p limit 500
UNION
match p = (n:Person)-[r*1..4]-(m:Phone)
where n.identificationNumber in ["xxx","yyy"] and m.phoneNumber in ["xxx","yyy"]
return p limit 500
UNION
...