Так что это интересная вещь, которая сосредотачивается вокруг того, что происходит, когда строки фильтруются (например, когда происходит сбой MATCH или условие WHERE фильтрует строку).
Но сначала нам нужно обратиться к тому, что вы наблюдаливо втором случае: Returns 0 and 0
.Я не думаю, что это действительно так, и я хотел бы знать, какую версию Neo4j вы здесь используете.В этом конкретном случае я бы вместо этого ожидал, что строки не будут возвращены, и это ПОЛНОСТЬЮ отличается от строки, возвращаемой с 0 значениями для обоих.
При выполнении запросов Cypher они создают записи (или строки) данных.И операции Cypher выполняются для каждой строки.Поэтому, когда вы выполняете MATCH в какой-то момент в вашем запросе, это выполняется для каждой строки, а когда происходит сбой MATCH, когда такой шаблон не существует (который соответствует вашему предложению WHERE, если имеется), тогда строка отфильтровывается.Это важно, потому что это означает, что любые другие данные в этой записи исчезли и перестали быть адресуемыми.
Второе, что нужно иметь в виду, это то, что мы разрешаем определенным агрегациям, таким как count()
и collect()
,выполнить , даже если нет строк , поскольку вполне возможно, что у вас может быть запрос, в котором ничего не совпадает, и получение этого числа 0 (или той пустой коллекции, когда вы собираете) является полностью допустимым случаем и должноразрешено.В этих случаях, когда после MATCH или фильтра может вообще не остаться ни одной строки (и из-за отсутствия строк, больше ничего не сможет быть выполнено, так как операции Cypher выполняются для каждой строки, поэтому нет возможности работать, если естьбез строк), count()
или collect()
приведет к появлению новой строки с этим счетчиком 0 или этой пустой коллекцией.И поскольку теперь есть строка, оставшимся операторам в запросе есть что выполнить, и запрос может продолжить выполнение.
Это то, что происходит в вашем первом случае, когда шаблон p1
не выполняетсуществует, но шаблон p2
существует (один раз).Вот описание того, что происходит:
- В первом совпадении ничего не найдено.Строки идут до 0. После выполнения следующих операций ничего не остается.
- Вы выполняете автономное агрегирование
count()
(без других переменных в области, это важно).Это выдает одну строку со счетчиком 0, и это правильно: на графике нет вхождений этого шаблона. - Вы выполняете второй MATCH, и есть запись / строка, которую он должен выполнить при(со значением
{failed_B2:0}
), и он находит единственное вхождение, и получает его счет (1), и может вывести ожидаемый ответ (1, 0), при этом 1 является счетчиком совпадений шаблона вконец запроса, p2, а 0 - количество совпадений шаблона из первых двух строк запроса, p1.
Теперь давайте посмотрим, что произойдет, когда мы перевернем это.
Во втором запросе теперь есть шаблон p1
, который существует один раз на графике, и шаблон p2
, который не существует.Вот разбивка, которая происходит:
- Первый матч успешно завершен и находит шаблон.
- Вы получаете количество найденных шаблонов: 1. Теперь у вас есть одна запись / строка сзначение
{failed_B2:1}
- Вы выполняете второе MATCH, а шаблон не найден.Запись / строка отфильтрованы.Теперь у вас нет записей / строк, поэтому не только нечего оперировать, но и все, что было ранее в записи / строках, пропало.НЕТ значения
failed_B2
для ссылки. - Вы пытаетесь получить счет
p2
вместе с failed_B2
. Но это не разрешено Cypher, мы разрешаем агрегацию только по 0 строкам, когда это автономный count () или collect (), там нет ссылки на failed_B2
, это было уничтожено, когда запись / строка, в которой она находилась, получила отфильтрованы Нет никакого способа обработать это разумно, поскольку ранее существовавшие данные просто отсутствуют (и это правильное поведение). Запрос должен возвращать без строк ... что НЕ совпадает с 0, 0
, так как это подразумевает, что вы вернули строку (вот почему я заинтересован в разъяснении этого вопроса с вами).
Что касается того, как вы должны правильно выполнять это, когда вам нужно агрегировать, как это, и вы знаете, что некоторые шаблоны могут не существовать, используйте ОПЦИОНАЛЬНОЕ МАТЧ вместо этого.
Когда вы выбираете опциональное совпадение, оно не отфильтровывает строку, если совпадение не найдено. Вместо этого вновь введенные переменные в шаблоне обнуляются, и когда вы считаете () или collect () больше нуля, он игнорирует их, давая вам правильный счет 0, но не стирая запись / строку, содержащую failed_B2
значение, которое вы также хотите вернуть в конце.