在Neo4j密码查询中创建TempArticle问题

rxztt3cl  于 2023-10-18  发布在  其他
关注(0)|答案(2)|浏览(137)

问:
我正在开发一个Neo4j Cypher查询,旨在更新或创建商店和文章之间的关系。目标是在现有关系的日期早于新日期时更新该关系,如果该关系不存在,则创建新的TempArticle节点并建立关系。然而,我写的代码似乎并没有像预期的那样工作。

:param { store_id: 22, article_name: "Candy shop", new_date: "2023-12-14", new_price: 32, article_description: "" };

MERGE (s:Store {store_id: $store_id, name: "STORE DEMO NAME"}); // testing store

MATCH (store:Store {store_id: $store_id})
OPTIONAL MATCH (store)-[rel:HAS_ARTICLE {article_name: $article_name}]->(article)
WITH store, rel, article,
     CASE
         WHEN rel IS NOT NULL AND rel.date < date($new_date) THEN true
         ELSE false
     END AS shouldUpdateRel,
     CASE
         WHEN rel IS NULL THEN true
         ELSE false
     END AS shouldCreateTempArticle
WITH store, rel, article, shouldUpdateRel, shouldCreateTempArticle
WHERE shouldUpdateRel
SET rel.date = date($new_date)
SET rel.prev_price = rel.price
SET rel.price = $new_price 
SET rel.article_name =  $article_name

WITH store, article, shouldCreateTempArticle
WHERE shouldCreateTempArticle
CREATE (tempArticle:TempArticle {article_name: $article_name, article_description: $article_description})
MERGE (store)-[newRel:HAS_ARTICLE]->(tempArticle)
SET newRel.date = date($new_date)
SET newRel.price = $new_price
SET newRel.article_name =  $article_name
RETURN store, article, shouldCreateTempArticle

问题:
该代码预计将更新现有关系,并在必要时使用新关系创建TempArticle节点。然而,我注意到,虽然关系更新部分似乎工作正常,但TempArticle创建部分的行为并不符合预期。尽管逻辑上表明当shouldtableTempArticle为true时它应该创建一个TempArticle,但它没有。
预期结果:
当shouldList TempArticle为true时,应创建一个新的TempArticle节点,该节点沿着与存储的关系。
当前结局:尽管设置了逻辑和条件,但TempArticle节点并未按预期创建。
我将感谢任何见解或建议,什么可能导致这个问题,以及如何解决它。提前感谢您的帮助!

dbf7pr2w

dbf7pr2w1#

relNULL时,则shouldCreateTempArticle为true,shouldUpdateRel为false。但是当shouldUpdateRel为false时,查询中的WHERE shouldUpdateRel子句将中止查询(针对相关行)。因此,当shouldUpdateRel为false时,查询中稍后出现的shouldCreateTempArticle逻辑将永远不会得到处理。
下面是一个解决方案,它使用两个CALL subquery子句来避免两个子查询相互干扰或最终返回值:

MATCH (store:Store {store_id: $store_id})
OPTIONAL MATCH (store)-[rel:HAS_ARTICLE {article_name: $article_name}]->(article)
WITH *,
  rel IS NOT NULL AND rel.date < date($new_date) AS shouldUpdateRel,
  rel IS NULL AS shouldCreateTempArticle
CALL {
    WITH *
    WITH * WHERE shouldUpdateRel
    SET rel.date = date($new_date)
    SET rel.prev_price = rel.price
    SET rel.price = $new_price 
    SET rel.article_name =  $article_name
}
CALL {
    WITH *
    WITH * WHERE shouldCreateTempArticle
    CREATE (tempArticle:TempArticle {article_name: $article_name, article_description: $article_description})
    MERGE (store)-[newRel:HAS_ARTICLE]->(tempArticle)
    SET newRel.date = date($new_date)
    SET newRel.price = $new_price
    SET newRel.article_name =  $article_name
}
RETURN store, article, shouldUpdateRel, shouldCreateTempArticle

该查询还返回两个标志(shouldUpdateRelshouldCreateTempArticle),以提示执行了什么操作。

8mmmxcuj

8mmmxcuj2#

是的,你永远不会遇到rel为null的情况,因为如果模式没有匹配,它不会超过可选的匹配。
你可以试试这个数据:

create (:Store {id:22,name:"STORE DEMO NAME"})-[:HAS_ARTICLE ]->(:Article {price :30,name:"Candy",date:"2023-12-13"});
:param {"data":[{"store_id": 22, "article_name": "Candy", "date": "2023-12-14", "price": 32},{"store_id": 22, "article_name": "Chocolate", "date": "2023-12-14", "price": 32},{"store_id": 22, "article_name": "Chocolate", "date": "2023-12-12", "price": 25}]}

然后运行此

unwind $data as art
match (store:Store {id: art.store_id})
merge (store)-[rel:HAS_ARTICLE]->(article:Article {name:art.article_name})
on create set article.date=art.date,article.price=art.price
with art,article where article.date<art.date
set article.date=art.date,article.price=art.price

这一切都在merge中,它创建了不存在的模式部分。这有点棘手,我发现这个视频有助于理解它是如何工作的https://www.youtube.com/watch?v=w42uqxGd7qM&t=12s
我没有把日期的关系,因为我不明白为什么你需要它旁边的文章
第一行数据更新“candy”,第二行创建“chocolate”,第三行被忽略,因为日期早于创建巧克力的日期

相关问题