我在Neo4j数据库中有3个带有标签的节点-应用程序,电话通讯录,短信。 我正在尝试编写类似的联系人和短信中的名称将检索所有应用程序ID的查询。 但是,我编写的查询执行了一段时间,并由于堆减少的错误而崩溃。 如何优化查询?
MATCH (pcb:PhoneContactsBook {phone: pcb.phone})-[:APP_PCB]->
(a:Applications)-[:APP_SMS]->
(sms:Sms {address: sms.address})
RETURN distinct pcb.phone,
collect(a.application_id);
我试图在用于过滤的字段(例如sms.address)上设置索引,但是它与它们的运行时间甚至更长。
答案 0 :(得分:2)
@stdob指出,MATCH
子句中的以下两个节点模式没有任何意义(很可能是导致崩溃的原因):
(pcb:PhoneContactsBook {phone: pcb.phone})
(sms:Sms {address: sms.address})
第一个节点模式正在寻找PhoneContactsBook
值等于自身的phone
节点,第二个节点模式正在寻找Sms
值等于自身的address
节点本身。由于这些模式将匹配所有PhoneContactsBook
和Sms
节点(只要它们分别具有phone
和address
属性),因此您的MATCH
子句最终会完成以下代码段的较昂贵版本,该代码段根本不按电话号码或地址进行过滤:
MATCH (pcb:PhoneContactsBook)-[:APP_PCB]->(a:Applications)-[:APP_SMS]->(sms:Sms)
因此,您的查询可能会导致大量匹配,这需要很长时间,并最终导致数据库用完堆。
您尚未提供有关数据模型的足够信息,让我知道如何解决此问题。但是,如果我正确地假设一个PhoneContactsBook
节点包含一个address
属性,而一个Sms
节点包含一个phone
属性,也许您是说以下意思?
MATCH (pcb:PhoneContactsBook {phone: sms.phone})-[:APP_PCB]->
(a:Applications)-[:APP_SMS]->
(sms:Sms {address: pcb.address})
RETURN distinct pcb.phone,
collect(a.application_id);
顺便说一句,您应该使用正确的术语。由于neo4j是图数据库,因此它没有“表”。相反,Applications
,PhoneContactsBook
和Sms
是节点“标签”。