diff --git a/pages/deployment/workloads/memgraph-in-cybersecurity.mdx b/pages/deployment/workloads/memgraph-in-cybersecurity.mdx index d95328aba..38266c935 100644 --- a/pages/deployment/workloads/memgraph-in-cybersecurity.mdx +++ b/pages/deployment/workloads/memgraph-in-cybersecurity.mdx @@ -281,4 +281,21 @@ SET n += props; This function **parses a JSON-formatted string into a Cypher map**, making it very useful for flexible security event ingestion pipelines where the event structure might vary slightly or be semi-structured. +### Setting nested properties + +Cybersecurity data often consists of nested objects (such as cloud security configurations) that are efficiently stored as maps. Many graph +database vendors do not support nested JSON objects and can only store them as strings within the property store. Memgraph, however, provides *full support +for nested objects*, including the ability to update them directly using queries such as the following: + +```cypher +MATCH (n:Node {id: 1}) SET n.details.created_at = date(), n.details.ip = '127.0.0.1'; +``` + +This approach keeps the configuration schema consistent with the original data sources powering your cybersecurity solution, eliminating the need for +manual and time-consuming graph modeling to represent configurations. In many cases, these configurations are so tightly coupled to the underlying objects +that there is no real need to separate them into distinct nodes and relationships. Attempting to do so can lead to *graph explosion* due to the large number +of values contained within nested configuration objects. + +For more information, read the [guide on setting nested propertes](/querying/clauses/set#9-setting-nested-properties). + diff --git a/pages/querying/clauses/set.md b/pages/querying/clauses/set.md index 828345054..cac29fe84 100644 --- a/pages/querying/clauses/set.md +++ b/pages/querying/clauses/set.md @@ -14,7 +14,9 @@ The `SET` clause is used to update labels on nodes and properties on nodes and r 5. [Remove a property](#5-remove-a-property)
6. [Copy all properties](#6-copy-all-properties)
7. [Replace all properties using map](#7-replace-all-properties-using-map)
-8. [Update all properties using map](#8-update-all-properties-using-map) +8. [Update all properties using map](#8-update-all-properties-using-map)
+9. [Setting nested properties](#9-setting-nested-properties)
+10. [Removing nested properties](#10-removing-nested-properties) ## Dataset @@ -221,6 +223,72 @@ Output: +-----------------------------------------------------------------------------------------------+ ``` +## 9. Setting nested properties + +Starting from **version 3.6**, Memgraph supports **nested properties**. Nested properties allow you to define and modify values inside `Map` property types. +Before nested property support was introduced, users could only set base properties using queries such as: +```cypher +MATCH (n:Person {name: 'Harry'}) SET n.age = 21; +``` + +With nested property support, you can now **set properties inside a map**, such as: +```cypher +MATCH (n:Person {name: 'Harry'}) SET n.details.age = 21; +``` + +If the `details` property does not already exist, Memgraph automatically creates it as a map and assigns the nested property within it. + +This feature is especially useful when working with configuration objects or when optimizing graph storage, since maps typically consume less memory than multiple node or relationship objects. + +You can query a nested property the same way you would any other: + +```cypher +MATCH (n:Person {name: 'Harry'}) +RETURN n.details.age AS age; + +Output: + +```nocopy ++-----+ +| age | ++-----+ +| 21 | ++-----+ +``` + +There are a few edge cases when working with nested properties: +If the parent property is not of type `Map`, the query will **throw an exception**: +```cypher +MATCH (n:Person {name: 'Harry'}) SET n.name.surname = 'Johnson' // ERROR because n.name is a string, not a map +``` + +{

Appending to nested properties

} + +You can also append to **existing map properties** using the `+=` operator: + +```cypher +MATCH (n:Person {name: 'Harry'}) SET n.details += {age: 21}; +``` + +When using this syntax: +- The **right-hand side** must be a `Map`. +- The **left-hand side** must also be a `Map` (and must exist). + +If either side is not a map, Memgraph will throw an exception. +This ensures that map merging is always type-safe and consistent. + +## 10. Removing nested properties + +Starting from version v3.6, Memgraph also supports removing nested properties for easier manipulation of map objects +within the node or relationship property store. The following query performs nested property removal: +```cypher +MATCH (n:Person {name: 'Harry'}) REMOVE n.details.age; +``` + +This removes only the specified nested property (`age`) while preserving all other keys in the parent map (`details`). + +If the property does not exist, Memgraph does not throw an exception - the behavior matches that of removing top-level properties. + ## Dataset queries We encourage you to try out the examples by yourself. diff --git a/pages/querying/read-and-modify-data.md b/pages/querying/read-and-modify-data.md index 53ff813a6..009fbc188 100644 --- a/pages/querying/read-and-modify-data.md +++ b/pages/querying/read-and-modify-data.md @@ -468,6 +468,37 @@ SET p1 = p2 RETURN p1, p2; ``` +#### Setting a nested property + +If the property of a node or relationship is a map, Memgraph supports setting nested +properties within the map for more granular updates. The following command updates a nested +property of a node: + +```cypher +MATCH (h:Person {name: 'Harry'}) +SET h.details.age = 21; +``` + +If the map property does not exist beforehand, it will be created as an empty map with the nested properties placed inside. +There are certain schema guarantees — you cannot modify a nested property if the parent property exists and is not of type `Map`. + +For more information, read the [guide on setting nested propertes](/querying/clauses/set#9-setting-nested-properties) + +#### Removing a nested property + +Similar to setting nested properties, Memgraph supports removing nested properties for more fine-grained manipulation of object data. +The following Cypher query deletes a nested property from a node: + +```cypher +MATCH (h:Person {name: 'Harry'}) +REMOVE h.details.age; +``` + +If the leaf property does not exist, the command will not raise an exception. +However, if the parent property maps do not exist, the query will result in a runtime exception. + +For more information, read the [guide on removing nested propertes](/querying/clauses/set#10-removing-nested-properties) + #### Bulk update You can use `SET` clause to do a bulk update. Here is an example of how to