Неожиданное поведение в цепочке Any () и None () в Neo4j - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь получить узлы, имеющие определенные значения свойств для любого имени свойства (ключа) и не имеющие каких-либо других значений для какого-либо свойства.

Короче говоря, псевдогугловский запрос будет выглядеть так:

+Tom +val1 +val2 (...) -Cruise -valX -valY (...)

и запрос Cypher будут выглядеть так:

MATCH (n) WHERE (
  ANY ( p in KEYS(n) WHERE n[p] CONTAINS 'Tom' ) AND
  NONE ( p in KEYS(n) WHERE n[p] CONTAINS 'Cruise')
)
RETURN n

Но результат теста с базой данных фильмов (: график воспроизведения фильма) был просто пустым списком, в то время как есть другие актеры с именем 'Том в базе данных, например Том Хэнкс.(match (n) где (any (p в KEYS (n), ГДЕ n [p] содержит 'Tom')) return n дает [Tom Tykwer, Tom Hanks, Tom Cruise, Tom Skerritt])

ИтакЯ экспериментировал с «ом» вместо «Том», и на этот раз результатом является неполный список «ом»:

match (n) where (
 any( p in KEYS(n) WHERE n[p] contains 'om') and 
 none( p in Keys(n) WHERE n[p] contains 'Cruise')
 )
 return n

дает

[Romantic (genre), Naomie Harris, James Thompson, Jessica Thompson]
(No Tom's -- why?)

Также пробовал НЕ ЛЮБОЙ () вместо NONE () и имели те же результаты.

Откуда возникает это несоответствие?

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

@ stdob-- предлагает точное объяснение проблемы.

Но есть более простые обходные пути.Например, вы можете использовать функцию COALESCE (), чтобы значение NULL обрабатывалось как FALSE:

MATCH (n)
WHERE
  ANY ( p in KEYS(n) WHERE n[p] CONTAINS 'Tom' ) AND
  NONE( p in KEYS(n) WHERE COALESCE(n[p] CONTAINS 'Cruise', FALSE))
RETURN n
0 голосов
/ 02 марта 2019

Проблема в том, что узлы имеют свойства с типом, отличным от string.И для них NONE-проверка дает null, что дает ошибку для where полностью.Например, этот запрос ничего не возвращает:

WITH {k1: 1, k2: '2'} AS test 
WHERE NONE(key IN keys(test) WHERE test[key] CONTAINS '1')
RETURN test

Так что в этом случае вам нужно проверить тип свойства.Поскольку нет встроенной функции проверки типа, вы можете использовать эту функцию из APOC library:

MATCH (n) WHERE (
  ANY(p in KEYS(n) WHERE apoc.meta.cypher.type(n[p]) = 'STRING' AND n[p] CONTAINS 'Tom') AND
  NONE(p in KEYS(n) WHERE apoc.meta.cypher.type(n[p]) = 'STRING' AND n[p] CONTAINS 'Cruise')
)
RETURN n
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...