Spring Data Neo4j находит узлы по нескольким массивам идентификаторов - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь написать запрос для поиска узлов по 3 другим узлам отношений:

@Query("MATCH " +
        "(n:DTTOVAR)-[cnorr:LIKE_CONSIGNOR]->(consignor:COMPANY), " +
        "(n:DTTOVAR)-[prodr:LIKE_PRODUCER]->(producer:COMPANY), " +
        "(n:DTTOVAR)-[cneer:LIKE_CONSIGNEE]->(consignee:COMPANY), " +
        "WHERE " +
        "id(consignor) in $0 AND id(producer) IN $1 AND id(consignee) IN $2 " +
        "RETURN n, cnorr, prodr, cneer, consignor, producer, consignee")
List<DTTovar> getAllByConsignorsProducersConsigneesPC(Long[] cnorsIds, Long[] producersIds, Long[] cneesIds);

Но !!! Мне нужно, если cnorsIds, sourcesIds или cneesIds будут нулевыми, чтобы исключить это условие из запроса или поиска всеми. Как это сделать?

Ответы [ 4 ]

0 голосов
/ 02 февраля 2020
@Query("OPTIONAL MATCH (n:DTTOVAR)-[cnorr:LIKE_CONSIGNOR]->(consignor:COMPANY) WHERE $0 IS NOT NULL AND id(consignor) IN $0 " +
 "OPTIONAL MATCH (n)-[prodr:LIKE_PRODUCER]->(producer:COMPANY) WHERE $1 IS NOT NULL AND id(producer) IN $1 " +
 "OPTIONAL MATCH (n)-[cneer:LIKE_CONSIGNEE]->(consignee:COMPANY) WHERE $2 IS NOT NULL AND id(consignee) IN $2 " +
 "OPTIONAL MATCH (n)-[coder:CLASSIFIED_IN]->(code:CUSTOMS_CODE) WHERE $3 IS NOT NULL AND id(consignee) IN $3 " +
 "WITH n MATCH (n:DTTOVAR)-[cnorr:LIKE_CONSIGNOR]->(consignor:COMPANY), " +
 "(n)-[prodr:LIKE_PRODUCER]->(producer:COMPANY), " +
 "(n)-[cneer:LIKE_CONSIGNEE]->(consignee:COMPANY), " +
 "(n)-[coder:CLASSIFIED_IN]->(code:CUSTOMS_CODE), " +
 "(n)-[e:REGISTERED_AT]->(d:H_DAY)-[r:DAY_OF]->(m:H_MONTH)-[t:MONTH_OF]->(y:H_YEAR) " +
 "WHERE case $0 IS NULL when FALSE then id(consignor) in $0 else true end " +
 "AND case $1 IS NULL when FALSE then id(producer) in $1 else true end " +
 "AND case $2 IS NULL when FALSE then id(consignee) in $2 else true end " +
 "AND case $3 IS NULL when FALSE then id(code) in $3 else true end " +
 "RETURN n, cnorr, consignor, prodr, producer, cneer, consignee, coder, code, e,d,r,m,t,y")
List<DTTovar> getAllByConsignorsNNAndProducersAndConsigneesAndCustomsCode(Long[] cnorsId, Long[] producersId, Long[] cneesId, Long[] codesId);
0 голосов
/ 31 января 2020

Большое спасибо, киберсам. Я сравнил мой вариант и ваш: Это мой: PROFILE MATCH (n: DTTOVAR) - [cnorr: LIKE_CONSIGNOR] -> (грузоотправитель: COMPANY), (n) - [prodr: LIKE_PRODUCER] -> (производитель: COMPANY), (n) - [cneer: LIKE_CONSIGNEE] -> (грузополучатель: COMPANY), (n) - [coder: CLASSIFIED_IN] -> (код: CUSTOMS_CODE) (грузоотправитель) в [7065] else true end И регистр NULL равен NULL, когда FALSE затем id (продюсер) в NULL иначе истинный конец AND case [5928, 28769, 7067] IS NULL, когда FALSE затем id (consignee) в [5928, 28769 , 7067] иначе true конец И регистр null равен NULL, когда FALSE затем id (код) в null, иначе true end ВОЗВРАТ n, cnorr, грузоотправитель, prodr, производитель, клиент, грузополучатель, кодер, код

72490 всего дБ число совпадений за 79 мс.

И ваше: ПРОФИЛЬНОЕ ФАКУЛЬТАТИВНОЕ МАТЧ (n: DTTOVAR) - [cnorr: LIKE_CONSIGNOR] -> (грузоотправитель: COMPANY), ГДЕ [7065] НЕ НУЛЬ И ИД (грузоотправитель) в IN [7065] ] ДОПОЛНИТЕЛЬНОЕ МАТЧ (n) - [prodr: LIKE_PRODUCER] -> (производитель: КОМПАНИЯ), ГДЕ НУЛЬ НЕ НЕДЕЙСТВИТЕЛЕН И ИД (производитель) В НУЛЕ ОПТИО NAL MATCH (n) - [cneer: LIKE_CONSIGNEE] -> (грузополучатель: COMPANY), ГДЕ [5928, 28769, 7067] НЕ НЕДЕЙСТВИТЕЛЕН И id (грузополучатель) В [5928, 28769, 7067] ДОПОЛНИТЕЛЬНЫЙ МАТЧ (n) - [кодер : CLASSIFIED_IN] -> (code: CUSTOMS_CODE) WHERE NULL НЕ NULL И ID (code) IN NULL RETURN n, cnorr, грузоотправитель, prodr, производитель, клиент, получатель, кодер, код

716 всего дБ за 42 мс

Но количество узлов (n: DTTOVAR) различно (в вашем варианте 152 узла против 105 в моем.

Я пытаюсь это понять .... enter image description here

enter image description here

0 голосов
/ 31 января 2020

Еще одна картина результатов: (в вашем варианте есть несколько нежелательных узлов)

enter image description here

enter image description here

0 голосов
/ 31 января 2020

Этот логи запроса c в основном игнорирует термин MATCH, если его список идентификаторов null:

OPTIONAL MATCH (n:DTTOVAR)-[cnorr:LIKE_CONSIGNOR]->(consignor:COMPANY)
WHERE $0 IS NOT NULL AND id(consignor) in $0
OPTIONAL MATCH (n)-[prodr:LIKE_PRODUCER]->(producer:COMPANY)
WHERE $1 IS NOT NULL AND id(producer) IN $1
OPTIONAL MATCH (n)-[cneer:LIKE_CONSIGNEE]->(consignee:COMPANY)
WHERE $2 IS NOT NULL AND id(consignee) IN $2
RETURN n, cnorr, prodr, cneer, consignor, producer, consignee

Использование PROFILE в моей версии neo4j, я вижу что IS NOT NULL тест выполнен до , соответствующий соответствующий элемент OPTIONAL MATCH выполнен, так что это должно быть эффективным (до определенного момента).

Однако вы все еще собирается получить декартово произведение результатов, условия которых не игнорируются. Не ясно, приемлемо ли это для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...