With the following query :-
MATCH (a) WHERE a.qid = "nm1" AND (a.unmanaged IS NULL OR a.unmanaged = false)
OPTIONAL MATCH (a)-[r]->(b) // for only outward relationships of 'a'
RETURN a as resources, collect(r) as references
I am getting resources and references separately which I later merge using a logic.
Is there anyway I can tweak this query such that it returns me all merged by itself?
PS:- Merge in the sense, ith of references as value to key "references" in ith of resources.
An Example of resources:-
{
"identity": 0,
"labels": [
"cloudInfra"
],
"properties": {
"region": "Asia"
"metrics": {},
"qid": "nm1",
},
"elementId": "0"
}
An Example of references :-
[
{
"identity": 7,
"start": 1,
"end": 7,
"type": "LOCATION_HAS_ES",
"properties": {
"_fromUniqueId": "location-c4ff53c9-6122-4cb8-b6f2-466bd86056de",
"_edgeType": "LOCATION_HAS_ES",
"_toUniqueId": "env-da691052-c21b-4efb-aa44-ff59efaa79db"
},
"elementId": "7",
"startNodeElementId": "1",
"endNodeElementId": "7"
},
{
"identity": 5,
"start": 1,
"end": 5,
"type": "LOCATION_HAS_ES",
"properties": {
"_fromUniqueId": "location-c4ff53c9-6122-4cb8-b6f2-466bd86056de",
"_edgeType": "LOCATION_HAS_ES",
"_toUniqueId": "env-179b4b3c-d170-44f0-8800-ae0bdba56f8b"
},
"elementId": "5",
"startNodeElementId": "1",
"endNodeElementId": "5"
},
{
"identity": 1,
"start": 1,
"end": 3,
"type": "LOCATION_HAS_ES",
"properties": {
"_fromUniqueId": "location-c4ff53c9-6122-4cb8-b6f2-466bd86056de",
"_edgeType": "LOCATION_HAS_ES",
"_toUniqueId": "env-beacfc97-1e99-4fcc-888b-3c16e06ad609"
},
"elementId": "1",
"startNodeElementId": "1",
"endNodeElementId": "3"
},
]
Expected merge:-
{
"identity": 0,
"labels": [
"cloudInfra"
],
"properties": {
"region": "Asia"
"metrics": {},
"qid": "nm1",
"references": [
{
"identity": 7,
"start": 1,
"end": 7,
"type": "LOCATION_HAS_ES",
"properties": {
"_fromUniqueId": "location-c4ff53c9-6122-4cb8-b6f2-466bd86056de",
"_edgeType": "LOCATION_HAS_ES",
"_toUniqueId": "env-da691052-c21b-4efb-aa44-ff59efaa79db"
},
"elementId": "7",
"startNodeElementId": "1",
"endNodeElementId": "7"
},
{
"identity": 5,
"start": 1,
"end": 5,
"type": "LOCATION_HAS_ES",
"properties": {
"_fromUniqueId": "location-c4ff53c9-6122-4cb8-b6f2-466bd86056de",
"_edgeType": "LOCATION_HAS_ES",
"_toUniqueId": "env-179b4b3c-d170-44f0-8800-ae0bdba56f8b"
},
"elementId": "5",
"startNodeElementId": "1",
"endNodeElementId": "5"
},
{
"identity": 1,
"start": 1,
"end": 3,
"type": "LOCATION_HAS_ES",
"properties": {
"_fromUniqueId": "location-c4ff53c9-6122-4cb8-b6f2-466bd86056de",
"_edgeType": "LOCATION_HAS_ES",
"_toUniqueId": "env-beacfc97-1e99-4fcc-888b-3c16e06ad609"
},
"elementId": "1",
"startNodeElementId": "1",
"endNodeElementId": "3"
},
],
},
"elementId": "0"
}
When a node or relationship property is a list, the list can only contain "primitive" types (like strings and integers), but not maps or sub-lists. So what you want to do is not possible.
And it is also not good practice to redundantly store a copy of data from a node's relationships into the node. The copied data will become inconsistent as soon as any of the relationships change, get deleted, or new relationships ones are added. You also increase the amount of storage needed. You should just get the relationship data directly from the relationships.
[UPDATE]
On the other hand, if you don't want to store relationship data in cloudInfra
nodes, but just want to return each matching cloudInfra
node's properties combined with a references
list (containing the node's outgoing relationship data), you can do the following. The APOC function apoc.map.merge is used to combine the data.
MATCH (a:cloudInfra) WHERE a.qid = "nm1" AND (a.unmanaged IS NULL OR a.unmanaged = false)
OPTIONAL MATCH (a)-[r]->(b) // for only outward relationships of 'a'
WITH a, COLLECT(r) AS references
RETURN apoc.map.merge(a, {references: references}) AS combination