Trabajando con nodejs y neo4j. Tengo la etiqueta de nodo: Product
. una de sus propiedades son entries
: que es un json de cadena, que contiene objetos anidados de tipo entry
.
cada vez que un usuario ingresa un enlace de producto, la cantidad de su entrada se incrementa.
Por ejemplo: al ingresar el enlace del producto desde la página de Facebook, se debe incrementar la cantidad de entradas de la página de Facebook.
( productId
. de producto y entry
son argumentos del extremo del servidor que enrutan a esa consulta.) la consulta actual:
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
con una entrada (página de Facebook), la consulta funciona bien.
pero con más de uno (por ejemplo: instagramPage), necesito una forma de guardar los datos de las entradas anteriores.
con javascript hubiera hecho algo como esto:
SET p.entries = apoc.convert.toJson({...jsonEntries, $entry: { link: jsonEntries.link, amount: jsonEntries.amount + 1, min: 1 }}})
¿Hay alguna manera de lograr este comportamiento?
vi la notación de puntos APOC para destruir el objeto json.
usándolo con mi caso, se vería algo como esto
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
pero esto requiere especificar cualquiera de las entradas, lo cual no se desea. Habrá muchas entradas y hará que la consulta sea difícil de mantener. además, la consulta deberá actualizarse cada vez que haya una nueva entrada.
estructura del producto:
{ "entries": "{"facebookPage":{"amount":1,"link":"www.facebook.com"},"instagram":{"amount":1,"link":"www.IG.com"}}", "id": "b80a61ea4a40408f847214fa3ccf9067", "title": "Guitar" } }
estructura de entrada:
{ amount: 0, link: 'some-link.com', }
La desestructuración que está utilizando no es una función APOC, sino solo Neo4j de vainilla. Puede desestructurar todas las propiedades usando el selector .*
; vea el último ejemplo en la página de documentación de proyección de mapas .
Entonces, para ti, reemplazaríamos .instagramPage
con .*
:
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
Aquí hay un ejemplo mínimo que muestra .*
trabajando solo para jugar:
WITH {instagramPage: {link: "instagram.com"}} AS entry RETURN entry {.*, facebookPage: {link: "facebook.com"}} Output: { "facebookPage": { "link": "facebook.com" }, "instagramPage": { "link": "instagram.com" } }
Felizmente, la desestructuración de esta manera también reemplaza los campos existentes en el mapa con valores actualizados cuando hay una colisión:
WITH {instagramPage: {link: "instagram.com"}} AS entry RETURN entry {.*, instagramPage: {link: "newinstagram.com"}} Output: { "instagramPage": { "link": "newinstagram.com" } }