In this article, we will model a graph network for managing home devices using Neo4j Aura and Cypher.
With the rise of digitalization, it has become common for individuals to own multiple devices.
People often have more than one smartphone, a work laptop, a tablet for home use, a wearable device on their wrist, a computer connected to their TV, and various other home devices and gaming consoles. The number of devices in a household continues to grow.
Let's assume there is a need to develop an application that can manage all personal devices within a household, visualizing OS updates, maintenance, and account usage.
As a solution, we will create a graph network representing a simple Mobile Device Management System (MDM).
Alice owns an iPhone 13 and a MacBook Pro 16-inch. We will represent her with a User
node and her devices with Device
nodes, connected by the [:OWNS]
relationship.
CREATE (u:User {name: 'alice'}),
(u)-[:OWNS]->(d1:Device:Asset:Mobile {id: 1, name: 'iPhone 13'}),
(u)-[:OWNS]->(d2:Device:Asset:Computer {id: 2, name: 'Macbook Pro 16 inch'});
One approach to modeling devices is to use only a generic Device
label and store the type as a property, such as Device {type: 'iPhone'}
.
However, a common use case is querying for all iPhones owned by a household. In such cases, it is more efficient to use multiple labels (Mobile
, Computer
, etc.) rather than relying on properties.
Additionally, ensuring that every device has a Device
label allows for queries that retrieve all devices in a household.
Bob owns multiple devices. Let's add his data to the existing graph network.
CREATE (u:User {name: 'bob'}),
(u)-[:OWNS]->(d1:Device:Asset:Mobile {id: 3, name: 'iPhone 10'}),
(u)-[:OWNS]->(d2:Device:Asset:Computer {id: 4, name: 'Macbook Air 13 inch'}),
(u)-[:OWNS]->(d3:Device:Asset:Computer {id: 5, name: 'Macbook Pro 16 inch'}),
(u)-[:OWNS]->(d4:Device:Asset:Smartwatch {id: 6, name: 'Apple Watch Series 7'});
Let's also define the relationship between Alice and Bob. They are parent and child.
MATCH (a:User), (b:User)
WHERE a.name = 'alice' AND b.name = 'bob'
CREATE (a)-[:PARENTS_OF]->(b), (b)-[:CHILD_OF]->(a);
At this stage, the graph network should look like this:
For example, to retrieve all Mobile
devices in the household, use the following Cypher query:
MATCH (m:Mobile) RETURN m.id, m.name;
To retrieve all Computer
devices owned by Bob:
MATCH (u:User)-[:OWNS]->(c:Computer)
WHERE u.name = 'bob'
RETURN u.name, c.id, c.name;
Now, let's manage devices by product type. For instance, we may want to track which users own different iPhone models.
To achieve this, we will introduce Product
nodes and link them to existing Device
nodes.
CREATE (p:Product {name: 'Macbook'});
MATCH (p:Product), (d:Device)
WHERE p.name = 'Macbook' AND d.name IN ['Macbook Air 13 inch', 'Macbook Pro 16 inch']
CREATE (d)-[:PRODUCTS_OF]->(p);
CREATE (p:Product {name: 'iPhone'});
MATCH (p:Product), (d:Device)
WHERE p.name = 'iPhone' AND d.name IN ['iPhone 13', 'iPhone 10']
CREATE (d)-[:PRODUCTS_OF]->(p);
CREATE (p:Product {name: 'Apple Watch'});
MATCH (p:Product), (d:Device)
WHERE p.name = 'Apple Watch' AND d.name IN ['Apple Watch Series 7']
CREATE (d)-[:PRODUCTS_OF]->(p);
At this stage, the updated graph network should look like this:
To find all iPhone products owned by Alice, use:
MATCH (u:User)-[:OWNS]->(d:Device)-[:PRODUCTS_OF]->(p:Product)
WHERE p.name = 'iPhone' AND u.name = 'alice'
RETURN d, p, u;
Now, suppose we want to query all devices produced by Apple Inc.. We can introduce a Company
node and connect it to Product
nodes.
CREATE (c:Company {name: 'Apple Inc.'});
MATCH (p:Product), (c:Company)
WHERE c.name = 'Apple Inc.' AND p.name in ['Macbook', 'iPhone', 'Apple Watch']
CREATE (c)-[:PRODUCES]->(p);
To list all devices produced by Apple Inc. along with their owners:
MATCH (u:User)-[:OWNS]->(d:Device)-[:PRODUCTS_OF]->(p:Product)<-[:PRODUCES]-(c:Company)
WHERE c.name = 'Apple Inc.'
RETURN u.name, d.name, p.name;
At this stage, the graph network should look like this:
In this tutorial, we explored data modeling for home device management using Neo4j and Cypher.
Experiencing different data modeling patterns is an excellent way to learn graph database techniques.
Neo4j is schema-less, allowing us to modify the data model dynamically without breaking existing relationships. You can extend this example by adding more custom requirements and experimenting with data modeling.
Why not try adding your own features and refining the model further?