使用nodejs和neo4j。我有节点标签:Product
。它的属性之一是entries
:这是一个字符串化的json,包含类型为entry
的嵌套对象。
当用户输入产品链接时,其输入的数量会增加。
例如:从Facebook页面输入产品链接,facebookPage条目的数量应该增加。
(productId
和entry
是路由到该查询的服务器端点的参数。(当前查询:
MATCH (p:Product {id: $prodcutId})
WITH apoc.convert.fromJsonMap(p.entries).facebookPage AS jsonEntries, p
SET p.entries = apoc.convert.toJson({facebookPage: { link: jsonEntries.link, amount: jsonEntries.amount + 1}})
RETURN p as product
有了一个条目(facebookPage(,查询就可以正常工作了。
但对于多个条目(例如:instagramPage(,我需要一种方法来保存以前的条目数据。
使用javascript,我会做这样的事情:
SET p.entries = apoc.convert.toJson({...jsonEntries, $entry: { link: jsonEntries.link, amount: jsonEntries.amount + 1, min: 1 }}})
有没有办法实现这种行为?
我看到了用于破坏json对象的APOC点符号。
链接到文档
在我的案例中使用它,它会看起来像这个
MATCH (p:Product {id: 'b80a61ea4a40408f847214fa3ccf9067'})
WITH apoc.convert.fromJsonMap(l.entries) AS jsonEntries, l
SET l.entries = apoc.convert.toJson(jsonEntries{.instagramPage, facebookPage: { link: jsonEntries.facebookPage.link, amount: jsonEntries.amount + 1 }})
RETURN l as p
但这需要指定任何一个条目,这是不需要的。将会有很多条目,这将使查询难以维护。此外,每当出现新条目时,都需要更新查询。
产品结构:
{
"entries": "{"facebookPage":{"amount":1,"link":"www.facebook.com"},"instagram":{"amount":1,"link":"www.IG.com"}}",
"id": "b80a61ea4a40408f847214fa3ccf9067",
"title": "Guitar"
}
}
入口结构:
{
amount: 0,
link: 'some-link.com',
}
您使用的析构函数没有APOC功能,只有香草Neo4j。您可以使用.*
选择器销毁所有属性——请参阅地图投影文档页面上的最后一个示例。
那么,我们将用.*
:替换.instagramPage
MATCH (p:Product {id: 'b80a61ea4a40408f847214fa3ccf9067'})
WITH apoc.convert.fromJsonMap(l.entries) AS jsonEntries, l
SET l.entries = apoc.convert.toJson(jsonEntries{.*, facebookPage: { link: jsonEntries.facebookPage.link, amount: jsonEntries.amount + 1 }})
RETURN l as p
下面是一个显示.*
只是用来玩的最小示例
WITH {instagramPage: {link: "instagram.com"}} AS entry
RETURN entry {.*, facebookPage: {link: "facebook.com"}}
Output:
{
"facebookPage": {
"link": "facebook.com"
},
"instagramPage": {
"link": "instagram.com"
}
}
令人高兴的是,当发生冲突时,以这种方式销毁还会用更新的值替换地图中的现有字段:
WITH {instagramPage: {link: "instagram.com"}} AS entry
RETURN entry {.*, instagramPage: {link: "newinstagram.com"}}
Output:
{
"instagramPage": {
"link": "newinstagram.com"
}
}