我试图在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
此查询在&lt; 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编码的新手,但我不得不想象有一种更好的方法来编写这个查询以提高效率。收藏如何改善这一点?
由于
答案 0 :(得分:0)
我已经在谷歌小组上回答了这个问题:
嗨斯科特,
我假设您为: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)鉴定由Staph属和Strep属包括的所有概念(包括Staph和Genus Strep的概念),如下所示。注意:
与b MATCH(b)q =(c:ObjectConcept {Strep})&lt; - [:ISA *] - (d:ObjectConcept),h =(e:ObjectConcept {Staph})&lt; - [:ISA *] - (f:ObjectConcept)
这是&#34; p&#34;,&#34; q&#34;的路径的交叉积。和&#34; h&#34;,例如如果它们中的所有3个都返回1000条路径,那么您将在10亿条道路上行走!!
c)识别所有没有Strep的致病因子(即节点(q))或Staph(节点(h))的节点(p)如下:
b,c,d,e,f MATCH(b),(c),(d),(e),(f)WHERE(b) - () - &gt;(c)OR( b) - &gt;() - &gt;(d)OR(b) - &gt;() - &gt;(e)OR(b) - &gt;() - &gt;(f)返回不同的b.Name;
你不需要WITH甚至MATCH(b),(c),(d),(e),(f)
b和其他节点之间有什么联系?你有具体的吗?对于第一个,也缺少一个方向。
where子句可能是个问题,一般来说你想表明也许这个查询可以通过简单匹配的UNION更好地再现
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()函数找到肺炎与具有某些相关类型和方向的细菌之间的一条或全部最短路径。
也许您可以共享数据集和预期结果。
答案 1 :(得分:0)
使用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分钟运行。