#neo4j #cypher
#neo4j #cypher
Вопрос:
Схема
У меня есть довольно простой match
запрос, который я хочу получить, чтобы получить результаты, в которых значение score
поля равно или больше параметра. (10 в приведенном ниже)
Код
MATCH (u:data)
WHERE u.score >= "10"
RETURN id(u) AS id, u.score AS score
LIMIT 10
Вывод
В настоящее время я получаю следующий ответ
╒══════╤══════════════╕
│"id" │"score" │
╞══════╪══════════════╡
│906674│"860" │
├──────┼──────────────┤
│906676│"1000" │
├──────┼──────────────┤
│906677│"860" │
├──────┼──────────────┤
│906879│"860" │
├──────┼──────────────┤
│906882│"260" │
├──────┼──────────────┤
│906888│"360" │
├──────┼──────────────┤
│906989│"2100" │
├──────┼──────────────┤
│907065│"1160" │
├──────┼──────────────┤
│907107│"260" │
├──────┼──────────────┤
│907152│"5" │
└──────┴──────────────┘
Как вы можете видеть, в последней строке есть оценка 5
, которая, очевидно, не >= 10
Вещи, которые я пробовал
WHERE u.score >= 10
возвращает 0 строк
WHERE u.score >= '10'
возвращает ошибку
Заранее благодарю вас за помощь!!
Ответ №1:
Похоже, что вы сохраняете числовую информацию в виде текста — в этот момент операторы сравнения> и < не выполняют то, что вы думаете, что они делают. Neo4j также не будет выполнять преобразование типов для вас — вот почему, когда вы пытаетесь сравнить с числом 10, а не со строкой 10, вы вообще не получаете результатов (он просто отклоняет все узлы, потому что тип данных не соответствует тому, что вы запрашиваете).
Например:
WITH "5" as a, "10" as b
RETURN a > b
╒═══════╕
│"a > b"│
╞═══════╡
│true │
└───────┘
Насколько я понимаю, Cypher выполнит посимвольное сравнение, когда вы спросите его: «какая строка больше?». Итак, в вашем случае он посмотрит на 5 и 10 и скажет
Является ли первый символ строки ‘5’ больше первого символа строки ’10’? Хорошо в ASCII 5> 1, так что да — возвращает true
Вам либо нужно сохранить числовую информацию в виде фактических чисел в свойствах узла (в этот момент сравнения будут работать так, как вы ожидаете), либо преобразовать свойство узла в число перед выполнением сравнения. Второй вариант может быть немного медленнее, потому что преобразование должно происходить на каждом узле, и вы не можете добавить полезный индекс, чтобы помочь.
Тем не менее, учитывая:
CREATE (a: Node { prop: "5" }), (b: Node { prop: "10" })
Затем
MATCH (n:Node) WHERE n.prop >= 10
RETURN n
не возвращает результатов, которые вы видите. Но:
MATCH (n:Node) WHERE toInteger(n.prop) >= 10
RETURN n
Возвращает искомый узел.
Однако, как уже упоминалось, я настоятельно рекомендую обновить ваши узлы, чтобы сохранить свойство score в виде числа, а не строки, если это действительно числовая информация.
Комментарии:
1. Спасибо за исчерпывающий ответ @Pablissimo — Очень признателен! Коэффициент детализации и понятности — 10/10!!