Совпадение нескольких таблиц оптимизации Neo4j - PullRequest
0 голосов
/ 30 сентября 2018

У меня есть 3 узла с метками в базе данных Neo4j - Приложения, Телефонная книга контактов, SMS.Я пытаюсь написать запрос, который по аналогичным контактам и именам в смс будет получать все идентификаторы приложений.Однако написанный мной запрос выполняется некоторое время и завершается с ошибкой об уменьшении кучи.Как я могу оптимизировать свой запрос?

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), но с ними он работает еще дольше.

Вотплан запроса: enter image description here

1 Ответ

0 голосов
/ 30 сентября 2018

Как указывает @stdob, 2 следующих шаблона узла в вашем предложении 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 являются "метками" узла.

...