我正在尝试查询Neo4j v2.1.5中表示为无环有向图的健康本体。数据库由200万个节点和500万条边/关系组成。以下查询标识包含在疾病概念中并由特定细菌或任何细菌亚型引起的所有节点,如下所示:
MATCH p = (a:ObjectConcept{disease}) <-[:ISA*]- (b:ObjectConcept),
q=(c:ObjectConcept{bacteria})<-[:ISA*]-(d:ObjectConcept)
WHERE NOT (b)-->()--(c) AND NOT (b)-->()-->(d)
RETURN distinct b.sctid, b.FSN此查询运行时间不到1秒,并返回正确答案。然而,添加一个额外的参数会增加大量的时间(20分钟)。示例:
MATCH p = (a:ObjectConcept{disease}) <-[:ISA*]- (b:ObjectConcept),
q=(c:ObjectConcept{bacteria})<-[:ISA*]-(d:ObjectConcept),
t=(e:ObjectConcept{bacteria})<-[:ISA*]-(f:ObjectConcept),
WHERE NOT (b)-->()--(c)
AND NOT (b)-->()-->(d)
AND NOT (b)-->()-->(e)
AND NOT (b)-->()-->(f)
RETURN distinct b.sctid, b.FSN我对cypher编码还不熟悉,但我必须想象有一种更好的方法来编写这个查询,以提高效率。集合将如何改善这一点?
谢谢
发布于 2015-03-22 23:24:26
我已经在google组上回答了这个问题:
嗨,斯科特
我假设您为:ObjectConcept(name)创建了索引或约束?
我正在使用一个无环的有向图(一个本体论),它对人类健康进行建模,并且需要识别某些具有传染性但不是由某些细菌(葡萄球菌或链球菌)引起的疾病(例如:肺炎)。所有概念都是定义为ObjectConcepts的节点。ObjectConcepts通过诸如ISA、Pathological_process、Causative_agent等关系进行连接。
查询要求:
a)识别肺炎概念所包含的所有概念,如下所示:
MATCH p = (a:ObjectConcept{Pneumonia}) <-[:ISA*]- (b:ObjectConcept)
this already returns a number of paths, potentially millions, can you check that with
MATCH p = (a:ObjectConcept{Pneumonia}) <-[:ISA*]- (b:ObjectConcept) return count(*) b)识别葡萄球菌属和链球菌属包含的所有概念(包括葡萄球菌属和链球菌属的概念),如下所示。注意:
其中b匹配(b) q= (c:ObjectConcept{Strep})<-:ISA*-(d:ObjectConcept),h= (e:ObjectConcept{Staph})<-:ISA*-(f:ObjectConcept)
这是来自"p","q“和"h”的路径的叉积,例如,如果这3个都返回1000条路径,那么你就是10亿条路径!!
c)识别不具有链球菌(即,节点(Q))或葡萄球菌(节点(H))的致病因子的所有节点(P),如下所示:
与b,c,d,e,f匹配(b),(c),(d),(e),(f)其中(b)--()-->(c) OR (b)-->()-->(d) OR (b)-->()-->(e) OR (b)-->()-->(f)返回distinct b.Name;
你不需要WITH,甚至 (b),(c),(d),(e),(f)
b和其他节点之间有什么连接?你们有混凝土的吗?对于第一个方向,也缺少一个方向。
联合where子句可能是个问题,通常您希望表明,使用简单匹配的联合可能会更好地重现此查询
e.g
MATCH (a:ObjectConcept{Pneumonia}) <-[:ISA*]- (b:ObjectConcept)-->()-->(c:ObjectConcept{name:Strep}) RETURN b.name
UNION
MATCH (a:ObjectConcept{Pneumonia}) <-[:ISA*]- (b:ObjectConcept)-->()-->(e:ObjectConcept{name:Staph}) RETURN b.name
UNION
MATCH (a:ObjectConcept{Pneumonia}) <-[:ISA*]- (b:ObjectConcept)-->()-->(d:ObjectConcept)-[:ISA*]->(c:ObjectConcept{name:Strep}) return b.name
UNION
MATCH (a:ObjectConcept{Pneumonia}) <-[:ISA*]- (b:ObjectConcept)-->()-->(d:ObjectConcept)-[:ISA*]->(c:ObjectConcept{name:Staph}) return b.name另一种选择是利用shortestPath()函数找到肺炎和细菌之间具有特定关系类型和方向的一条或所有最短路径。
也许您可以共享数据集和预期结果。
发布于 2015-03-31 05:44:37
查询是使用UNION函数成功完成的,如下所示:
MATCH p = (a:ObjectConcept{sctid:233604007}) <-[:ISA*]- (b:ObjectConcept),
q = (c:ObjectConcept{sctid:58800005})<-[:ISA*]-(d:ObjectConcept)
WHERE NOT (b)-->()--(c) AND NOT (b)-->()-->(d)
RETURN distinct b
UNION
MATCH p = (a:ObjectConcept{sctid:233604007}) <-[:ISA*]- (b:ObjectConcept),
t = (e:ObjectConcept{sctid:65119002}) <-[:ISA*]- (f:ObjectConcept)
WHERE NOT (b)-->()-->(e) AND NOT (b)-->()-->(f)
RETURN distinct b通过减少被查询对象的基数,查询运行时间从20分钟减少到20秒。
https://stackoverflow.com/questions/29178453
复制相似问题