neo4j — объявляет переменные, доступные для создания узла в предложении FOREACH, а также для предложения RETURN

#neo4j #cypher #neo4j-driver

#neo4j #cypher #neo4j-драйвер

Вопрос:

Я работаю над графиком neo4j со следующими метками: Магазин, Пользователь, Продукт

отношения следующие: (магазин)-[:OF]-> (пользователь), (продукт)-[:OF]-> (пользователь), (магазин)-[:ПРОДАТЬ]-> (продукт)

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

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

 OPTIONAL MATCH (user: User {id: $userId} )
CREATE (store:Store)-[:OF]->(user)
SET store = $store
WITH store, user
OPTIONAL MATCH (p: Product {id: "hu1"})-[:OF]->(user)  
WITH store, p,  
CASE WHEN NOT (:Store)-[:SELL]->(p) OR                 
(:Store {id: '12asd'})-[:SELL]->(p) THEN [1]      
ELSE [] END as array              
FOREACH(
    x in array |              
    MERGE (p)-[:OF]->(user)          
    ON MATCH SET p  = $product1         
    ON CREATE SET p = $product1         
    MERGE (store)-[:SELL]->(p)         
) 
RETURN store, p
  

(может показаться странным, что одним из моих условий является проверка идентификатора хранилища, когда я только что его создал, но этот запрос в коде обрабатывает больше ситуаций, когда это необходимо, и я не собираюсь возиться со всем кодом)

необходимая модификация — перенести создание хранилища в инструкцию FOREACH, потому что я не буду создавать хранилище, если один из продуктов не передал одно из условий ОБРАЩЕНИЯ.

я попытался переместить создание хранилища внутри инструкции FOREACH с помощью MERGE —

 OPTIONAL MATCH (user: User {id: $userId} ) 
WITH user
OPTIONAL MATCH (p: Product {id: "1"})-[:OF]->(user)  
WITH p,  
CASE WHEN NOT (:Store)-[:ON]->(p) OR                 
(:Store {id: 'st'})-[:ON]->(p) 
THEN [1]      
ELSE [] END as array              
FOREACH(
    x in array |              
    MERGE (p)-[:OF]->(user)          
    ON MATCH SET p  = $product1         
    ON CREATE SET p = $product1         
    MERGE (store:Store {id: 'st'})
    ON MATCH SET store  = $store         
    ON CREATE SET store = $store         
    MERGE (store)-[:ON]->(p)         
) 
RETURN store, p 
  

но я получил эту ошибку:

Neo4jError: переменная store не определена

указывая на store переменную в инструкции RETURN.

я попытался добавить еще один оператор WITH между FOREACH и RETURN, но я получил ту же ошибку, указывающую только на переменную store в предложении WITH.

как я могу объявить переменную вне предложения FOREACH, чтобы я мог создать для нее узел в FOREACH, а также использовать его в ВОЗВРАТЕ?

Ответ №1:

Попробуйте объявить свои параметры вне FOREACH инструкции:

 OPTIONAL MATCH (user: User {id: $userId} ) 
WITH user
OPTIONAL MATCH (p: Product {id: "1"})-[:OF]->(user)  
WITH p,  
     CASE WHEN NOT (:Store)-[:ON]->(p) OR                 
                   (:Store {id: 'st'})-[:ON]->(p) 
                   THEN [1] ELSE [] END as array,
     $store as store,
     $product1 as product1              
FOREACH(
    x in array |              
    MERGE (p)-[:OF]->(user)          
    ON MATCH SET p  = product1         
    ON CREATE SET p  = product1         
    MERGE (s:Store {id: 'st'})
    ON MATCH SET s  = store         
    ON CREATE SET s  = store         
    MERGE (s)-[:ON]->(p)         
) 
RETURN store, p 
  

Комментарии:

1. привет, извините за задержку. я попробовал это и получил эту ошибку: несоответствие типов: хранилище определено с помощью конфликтующей карты типов. «ОБЪЕДИНИТЬ (хранилище: Store {id: ‘c34’})-[:OF]-> (user)». это указывает на хранилище при слиянии.