Использование карты в диапазоне ОПЦИОНАЛЬНОГО МАТЧА в Neo4j cypher - PullRequest
2 голосов
/ 18 апреля 2020

Я создаю Python Приложение, которое использует базу данных Neo4j для анализа словосочетаний. Я пытаюсь запросить слова, которые являются соседними в указанном диапазоне c прыжка. Я использую Flask для вызовов REST и драйвер neo4j для Python для запросов. Мой текущий подход выглядит следующим образом:

def get_word(title, neighborhood_right_range):
    db = get_db()
    results = db.run("MATCH (word:Word {title:$title}) "
                     "OPTIONAL MATCH (word)-[:IS_NEIGHBORING*1..$neighborhood_right_range]-(word2:Word) WHERE NOT word2.title=$title "
                     "MATCH (t:Text)-[:CONTAINS]->(word:Word) "
                     "MATCH (t)-[:CONTAINS]->(word2) "
                     "RETURN word.title as title "
                     ", collect(DISTINCT word2.title) as neighbors "
                     "LIMIT 1", {"title": title, "neighborhood_right_range": neighborhood_right_range})
    result = results.single()
    return Response(dumps(word_service.format_word(result)),
                    mimetype="application/json")

и приводит к следующему:

neobolt.exceptions.CypherSyntaxError: Parameter maps cannot be used in MATCH patterns (use a literal map instead, eg. "{id: {param}.id}") (line 1, column 76 (offset: 75))
"MATCH (word:Word {title:$title}) OPTIONAL MATCH (word)-[:IS_NEIGHBORING*1..$neighborhood_right_range]-(word2:Word) WHERE NOT word2.title=$title MATCH (t:Text)-[:CONTAINS]->(word:Word) MATCH (t)-[:CONTAINS]->(word2) RETURN word.title as title , collect(DISTINCT word2.title) as neighbors LIMIT 1"

Я пытался использовать предложенную буквенную карту, но не смог найти правильный способ используйте это в этом контексте

1 Ответ

1 голос
/ 18 апреля 2020

Я не думаю, что вы можете параметризовать части шаблона, которые повлияют на компиляцию запроса.

Из документов :

Параметры нельзя использовать для следующих конструкций, поскольку они образуют часть структуры запроса, которая компилируется в план запроса:

  • ключи свойств; Итак, MATCH (n) WHERE n. $ param = 'что-то' недопустимо
  • типы отношений
  • метки

Вместо этого вы не можете использовать параметр для neighbourhood_right_range, но вставьте это значение в запрос, используя обычную Python интерполяцию или конкатенацию строк:

results = db.run("MATCH (word:Word {title:$title}) "
                 "OPTIONAL MATCH (word)-[:IS_NEIGHBORING*1.." + neighborhood_right_range + "]-(word2:Word) WHERE NOT word2.title=$title "
                 "MATCH (t:Text)-[:CONTAINS]->(word:Word) "
                 "MATCH (t)-[:CONTAINS]->(word2) "
                 "RETURN word.title as title "
                 ", collect(DISTINCT word2.title) as neighbors "
                 "LIMIT 1", {"title": title})

Имейте в виду, что, если окрестность_района_управляется каким-либо образом пользователем, вам необходимо санировать это таким образом, ввод как конкатенация запросов может представлять угрозу безопасности.

...