Imagine an item can be tagged by connecting unique tag nodes to a post with the twist that tags come from different sources. The source is recorded on the connecting edge, and there may be only one edge between a post and tag corresponding to the same source.
This query returns posts and their tags with the tag containing details of source and score:
project('title', 'tags').by('title').
by(inE().as('rel').
hasLabel('tags').project('value', '_rel').
by(outV().hasLabel('tag').values('value')).
by(project('score', 'source').
by('score').by('source')).
group().
by(values('value'))
)
The result is in the following shape:
[
{
"title": "x",
"tags": {
"dog": [
{
"value": "dog",
"_rel": {
"score": 5,
"source": "user"
}
}
],
"cat": [
{
"value": "cat",
"_rel": {
"score": 3,
"source": "user"
}
},
{
"value": "cat",
"_rel": {
"score": 2,
"source": "google"
}
}
]
}
}
]
Question is: how can this shape be transformed to the more compact form below?
{
"title": "x",
"tags": [
{
"value": "dog",
"_rel": [
{
"score": 5,
"source": "user"
}
]
},
{
"value": "cat",
"_rel": [
{
"score": 2,
"source": "google"
},
{
"score": 3,
"source": "user"
}
]
}
]
}
This is a typescript (and Neptune) implementation so some limitations apply.
A minimal sample graph is available at https://gremlify.com/khvizyzeqg and below:
property(single, 'value', 'cat').addV('tag').
as('2').
property(single, 'value', 'dog').addV('post').
as('3').
property(single, 'title', 'x').addE('tags').
from('1').to('3').property('score', 3).
property('source', 'user').
property('value', 'cat').addE('tags').
from('1').to('3').property('score', 2).
property('source', 'google').
property('value', 'cat').addE('tags').
from('2').to('3').property('score', 5).
property('source', 'user').
property('value', 'dog')