neo4j шифр — сопоставление запроса, извлекающего данные, которых нет в заданных параметрах

#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!!