В настоящее время я использую следующий запрос для удаления пакета узлов из моей базы данных графов Neo4j:
String cypherCascadeDel= "UNWIND $conditions AS cond " +
"MATCH (node:" + tableName + ") " +
"WHERE ALL(key IN keys(cond) WHERE node[key] = cond[key])"+
"DETACH DELETE node";
где условие — это список карт type<String,Object>
. Список может содержать до 1 миллиона записей, а каждая карта может содержать до 5 пар «ключ-значение».
Этот запрос выполняется долго — около 15–20 минут для 100 000 записей. Есть ли лучший способ масштабировать это?
Ваш предикат не позволяет выполнять поиск по индексу, поэтому выполняется сканирование меток.
Проблема в том, что ваш UNWIND генерирует строки, а операции в Cypher выполняются для каждой строки.
Таким образом, для 100 тысяч записей ваш UNWIND генерирует 100 тысяч строк, и поэтому MATCH вызывается 100 тысяч раз, что приводит к 100 тысячам выполнений NodeByLabelScan.
Вместо этого вы можете изменить свой подход, опустить UNWIND и попробовать это.
...
WHERE ANY(map IN $conditions WHERE ALL(key IN keys(map) WHERE node[key] = map[key]))
...
Это должно ограничить его одним NodeByLabelScan, и для каждого узла он проверит все условия карты в вашем списке, и как только он найдет одно, он примет узел для удаления и перейдет к следующему.
Это трудоемкая вещь. Но это то, что вы сказали, что хотите этого. В конце концов, цель запроса — выполнить какую-то работу, а работа, которую вы ему поручили, стоит дорого. Поскольку вы хотите, чтобы это происходило динамически с картами, нет возможности выполнить поиск по индексу. Остаётся только скан этикетки. И нет никакого способа узнать, соответствуют ли свойства узла какой-либо из карт, кроме как путем их сравнения.
Спасибо! Вышеупомянутый запрос показал некоторую экономию времени. Однако выигрыш гораздо меньше. Еще один вопрос, который у меня есть: не будет ли второй запрос также занимать много времени, поскольку список - моя программа состоит из большого количества записей? Итак, проверяя каждую узел со всеми картами в списке занимает много времени, не так ли?