Оптимизация запросов Neo4j Cypher - ручной указатель APOC по свойствам отношений - PullRequest
0 голосов
/ 29 апреля 2018

В соответствии с логикой приложения я реализовал собственный построитель запросов Cypher, который создает сложные запросы на основе пользовательского ввода из пользовательского интерфейса.

Вот пример таких запросов:

MATCH (dg:DecisionGroup)-[:CONTAINS]->(childD:Decision) 
WHERE dg.id = {decisionGroupId} 
MATCH (childD)-[relationshipValueRel2:HAS_VALUE_ON]-(filterCharacteristic2:Characteristic) 
WHERE filterCharacteristic2.id = 2 
WITH relationshipValueRel2, childD, dg 
WHERE   (ANY (id IN {relationshipValueRel21} WHERE id IN relationshipValueRel2.value ))  AND   ( relationshipValueRel2.`property.1.3` = {property2}  ) OR  ( relationshipValueRel2.`property.1.3` = {property3}  )  
WITH childD, dg  
MATCH (childD)-[relationshipValueRel3:HAS_VALUE_ON]-(filterCharacteristic3:Characteristic) 
WHERE filterCharacteristic3.id = 3 
WITH relationshipValueRel3, childD, dg 
WHERE   (relationshipValueRel3.`value` = 'London')  
WITH childD , dg  
SKIP 0 LIMIT 100 
WITH * 
MATCH (childD)-[ru:CREATED_BY]->(u:User) 
OPTIONAL MATCH (childD)-[rup:UPDATED_BY]->(up:User)  
RETURN ru, u, rup, up, childD AS decision, 
[ (dg)<-[:DEFINED_BY]-(entityGroup)-[:CONTAINS]->(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD)
 | {entityId: toInt(entity.id),  types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (c1)<-[vg1:HAS_VOTE_ON]-(childD)
 | {criterionId: toInt(c1.id),  weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
[ (dg)<-[:DEFINED_BY]-(chg:CharacteristicGroup)-[rchgch1:CONTAINS]->(ch1:Characteristic)<-[v1:HAS_VALUE_ON]-(childD) 
 | {characteristicId: toInt(ch1.id),  v1:v1, optionIds: v1.optionIds, valueIds: v1.valueIds, value: v1.value, available: v1.available, totalHistoryValues: v1.totalHistoryValues, totalFlags: v1.totalFlags, description: v1.description, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics

С небольшим числом child:Decision (например, <1000) он работает довольно быстро, но производительность заметно снижается после увеличения данных. </p>

Основной причиной этого является операция фильтрации, основанная на свойствах отношения, таких как:

WHERE (ANY (id IN {relationshipValueRel21} 
WHERE id IN relationshipValueRel2.value ))  
    AND ( relationshipValueRel2.`property.1.3` = {property2} ) 
    OR  ( relationshipValueRel2.`property.1.3` = {property3} ) 

Обратите внимание, что это всего лишь частный случай, и запрос, основанный на пользовательском вводе, может содержать десятки таких условий с (<, <=, =, >, >=, IN, ALL IN, ANY IN) операциями , где значением свойства может быть одно значение или массивы .

Прямо сейчас я думаю о том, как улучшить производительность этого запроса, потому что я ожидаю, что десятки или сотни тысяч child:Decision там. Чтобы сделать это, я изучаю Индекс руководства APOC по свойствам отношений

Принимая это во внимание - имеет ли смысл переопределить мой построитель запросов, чтобы использовать ручной указатель APOC для свойств отношений для упомянутой операции фильтрации, или это не поможет?

...