# NeuroDB Documentation
# Introduction
NeuroDB is an in-memory graph database engine that uses Neuro-cypher commands to create, edit, retrieve graph data, and build advanced graph applications based on complex graph algorithms. The main features of NeuroDB are:
- Lightweight: The entire engine executable is less than 400KB in size.
- In-memory: The entire graph data is loaded into memory for operations.
- High-speed: Due to the database being entirely in memory, there is no disk read/write latency.
- Embeddable: The database can be embedded into your project similar to SQLite, eliminating the need for separate deployment and operation.
- Multi-platform: NeuroDB can run on mainstream operating systems (Windows, Linux, Mac), mobile operating systems (Android, iPhone), and any embedded system or microcontroller (STM32) that can run C language target programs.
- Simplified: Similar to Redis, NeuroDB achieves a powerful, efficient, and low resource consumption graph database engine through simplified manipulation commands, simplified deployment and operation, and a simplified software architecture.
- Fully self-developed: Provides a domestic substitute solution for graph databases.
- Edge computing: Due to the lightweight nature of NeuroDB, it can be embedded in small and micro devices (on-chip) to achieve “edge computing”.
- Graph modeling concept: NeuroDB’s visual client implements the concept of “derived” graph data based on model-oriented modeling, allowing for designing node and relationship structures in modeling, and designing attributes on nodes or relationships similar to a relational database table structure (attribute name, attribute data type, attribute data length, etc.).
This tutorial will teach you all the techniques of NeuroDB in a minimalist style within 1 hour! Here we go!
# Download, Install, and Deploy
- Download and deploy the package: Before installation and deployment, we need to go to the “Download” page and download the NeuroDB package for your system. The installation and deployment process is very simple, just unzip the downloaded NeuroDB package to a directory where you usually place software.
- Docker deployment:
docker pull panggguoming/neurodb:1.0.0
The directory structure of the package is as follows:
Where:
- The bin directory contains the NeuroDB server and client executables.
- The data directory contains the data files for persistent storage.
- The import directory contains the data files to be imported (csv files).
- The logs directory contains the running logs.
After deployment:
- Start the NEURO_SERVER in the bin directory to start the NeuroDB server. By default, it occupies port 8839. If you want to change the port, you can learn how to do so in the subsequent “Operations and Management” chapter.
- Start the NEURO_CLI in the bin directory to start the command-line client. This client is set to connect to the local 8839 port by default. You can modify the default connection IP and port by adding the parameters “host 127.0.0.1 port 8839”. In the client, you can directly input commands and view the execution results.
- For a more visual and convenient way to run commands and view results, it is recommended to download and install the desktop version of “NeuroStudio”. “NeuroStudio” provides powerful and friendly visual UI components to improve the experience of operating and displaying graph data. In this tutorial, subsequent examples will use NeuroStudio screenshots to show results. Its installation and operation are very simple. After downloading and unzipping, run the “neuro-Studio.exe” in the root directory. “NeuroStudio” is an optional installation package. If the user only needs to run commands without visual display, there is no need to download and install “NeuroStudio”.
# Start NeuroDB
# windows System
Unzip the package to any directory and run NEURO_SERVER.exe in the bin directory. This is the NeuroDB server. It can also be run in the command line.
The command-line client is NEURO_CLI.exe, and it can be started after the server is started. If you need to input parameters to connect to a specific IP and port, you need to enter the following command in the command line to start it. After NEURO_CLI is started, we can directly input Neuro-Cypher commands in the command line and view the command line results.
# linux System
Unzip the program package to any directory. Grant executable permissions to the NEURO_SERVER in the bin directory.
chmod +x NEURO_SERVER
Run NEURO_SERVER.
./NEURO_SERVER
Alternatively, you can use the nohup command to run it in the background.
nohup ./NEURO_SERVER &
Then start the client to connect to the server and execute commands.
./NEURO_CLI
# Mac System
Unzip the program package to any directory and run the NEURO_SERVER in the bin directory.
./NEURO_SERVER
Then start the client to connect to the server and execute commands.
./NEURO_CLI
# Quick Start
# Create an Instance of Social Network
Create nodes for companies (Company), individuals (Person), and the work relationship between companies and individuals (WORK). Also create the friendship relationship between individuals (FRIEND), thus building a simple social network.
create
(Xiaomi:Company {name:"Xiaomi Technology Co., Ltd", create_at:2010, tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"})
, (Alibaba:Company {name:"Alibaba Group Holdings Limited", create_at:1999, tagline:"Intended to build future commercial infrastructure"})
, (Baidu:Company {name:"Baidu Online Network Technology Co., Ltd", create_at:2000, tagline:"It is a leading AI company with a strong internet foundation"})
, (Leimou:Person {name:"Lei", born:1969})
, (Mamou:Person {name:"Ma", born:1964})
, (Limou:Person {name:"Li", born:1968})
, (Chenmou:Person {name:"Chen", born:1960})
, (Zhangmou:Person {name:"Zhang", born:1967})
, (Wangmou:Person {name:"Wang", born:1965})
, (Zhaomou:Person {name:"Zhao", born:1952})
, (Leimou)-[:WORK {position:"CEO"}]->(Xiaomi)
, (Chenmou)-[:WORK {position:"staff"}]->(Xiaomi)
, (Mamou)-[:WORK {position:"CEO"}]->(Alibaba)
, (Zhaomou)-[:WORK {position:"staff"}]->(Alibaba)
, (Limou)-[:WORK {position:"CEO"}]->(Baidu)
, (Wangmou)-[:WORK {position:"staff"}]->(Baidu)
, (Zhangmou)-[:WORK {position:"staff"}]->(Baidu)
, (Wangmou)-[:FRIEND{weight:2}]->(Leimou)
, (Zhaomou)-[:FRIEND{weight:1}]->(Leimou)
, (Zhangmou)-[:FRIEND{weight:4}]->(Mamou)
, (Zhangmou)-[:FRIEND{weight:8}]->(Chenmou)
, (Chenmou)-[:FRIEND{weight:5}]->(Limou)
, (Mamou)-[:FRIEND{weight:10}]->(Limou)
After creating, the visualization effect is as follows:
# Query
- Query individuals with the name “Wang”.
MATCH (n:Person{name:"Wang"}) return n
result:
status:OK,cursor:40,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000}
2、Query individuals born after 1965.
MATCH (n:Person) where n.born > 1965 return n
result:
status:OK,cursor:45,result:3,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
(2)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(3)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000}
3、Query all “FRIEND” relationships.
MATCH (n)-[r:FRIEND]->(m) return n,r,m
result:
status:OK,cursor:38,result:6,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(2)-----------------------------------------------------------------------
ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(3)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000}
(4)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000}
(5)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000} ID:7 HEAD:8 TAIL:3 TYPE:FRIEND PROPS:{weight:2} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
(6)-----------------------------------------------------------------------
ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000} ID:8 HEAD:9 TAIL:3 TYPE:FRIEND PROPS:{weight:1} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
Visualization: 4、Query all “one-degree” relationships related to the individual “Li”.
MATCH (n:Person{name:"Li"})-[r]-(m) return n,r,m
result:
status:OK,cursor:52,result:3,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(2)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000}
(3)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000}
Visualization:
5、Find the company where “Zhang” works and all his colleagues.
MATCH (n:Person{name:"Zhang"})-[w1:WORK]-> (c:Company) <-[w2:WORK]-(n2) RETURN n,w1,c,w2,n2
result:
status:OK,cursor:93,result:2,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:6 HEAD:7 TAIL:2 TYPE:WORK PROPS:{} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"} ID:5 HEAD:8 TAIL:2 TYPE:WORK PROPS:{position:"staff"} ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000}
(2)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:6 HEAD:7 TAIL:2 TYPE:WORK PROPS:{} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
Visualization:
6、Query the shortest social network path between “Zhang” and “Zhao”. From the result, we find that “Zhang” is a friend of “Ma”, and “Ma” is a colleague in the same company as “Zhao”.
MATCH path=(start :Person{name:"Zhang"})-[rels *<]- (end :Person{name:"Zhao"}) RETURN path
result:
status:OK,cursor:95,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:2 HEAD:4 TAIL:1 TYPE:WORK PROPS:{position:"CEO"} ID:1 LABELS:Company PROPS:{name:"Alibaba Group Holdings Limited",create_at:1999.000000,tagline:"Intended to build future commercial infrastructure"} ID:3 HEAD:9 TAIL:1 TYPE:WORK PROPS:{position:"staff"} ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000}
Visualization:
# Modify
1、Add a gender attribute for individual “Zhang”.
MATCH (n :Person{name:"Zhang"}) set n.sex="male" return n
2、Change the gender attribute for individual “Zhang” to female.
MATCH (n :Person{name:"Zhang"}) set n.sex="女" return n
# Delete
When performing deletion operations, if a node has any relationship edges, it cannot be directly deleted. You need to delete all its related relationship edges before you can delete the node. Alternatively, you can use the “detach delete” command to delete all relationship edges and the node in one step.
1、Delete the “FRIEND” relationship between “Zhang” and “Ma”.
MATCH (n :Person{name:"Zhang"})-[r:FRIEND]->(m :Person{name:"Ma"}) DELETE r
2、Delete the node of individual “Zhang”. This command will prompt that it cannot be deleted because “Zhang” still has two related relationships. Only by deleting all the related relationships of this node with the above command, can this command be executed successfully.
MATCH (n :Person{name:"Zhang"}) DELETE n
3Delete the node of individual “Zhang” and all its related relationships at once. This command will not encounter the situation of being unable to delete because it is a one-step command that deletes all related relationships and then deletes the node.
MATCH (n :Person{name:"Zhang"}) DETACH DELETE n
# Conclusion
So far, we have quickly experienced an instance of NeuroDB for social networking. The data size of this instance is very small, but it makes it easier for us to run and understand. In actual applications, NeuroDB supports graphs composed of massive data.
# Neuro-cypher Command
Neuro-cypher is a declarative graph database query language that has rich expressiveness and can efficiently query and update graph data.
# Graph Data Structure
A graph is composed of nodes and relationships. Nodes may have labels and properties, and relationships have types and properties. Nodes represent entities, and relationships connect pairs of nodes. Nodes can be seen as tables in a relational database, but not exactly the same. The labels of nodes can be understood as table names in a relational database, and the properties are similar to columns in a table. The data of a node is similar to a row of data in a relational database. Nodes with the same label usually have similar properties.
# Pattern
We can encode complex ideas into numerous nodes and relationships using patterns. Neuro-cypher query language heavily relies on describing patterns. A pattern can be as simple as a pair of nodes connected by a relationship. For example, a person lives in a city or a city is part of a country. A pattern can also be complex, using multiple relationships to express complex concepts and support various interesting use cases. The following Cypher code connects two simple patterns together:
(:Person) -[:WORK]-> (:Company)
# Describing Nodes
Cypher uses a pair of parentheses to represent nodes, such as: () and (foo). Here are some common notations for nodes:
() -- empty node
(xiaomi) -- empty node with only a node variable name
(:Company) -- node with a node label definition
(xiaomi:Company) -- node with a node variable name and label definition
(xiaomi:Company {name: "xiaomi"}) -- node with a node variable name, label, and a name property
(xiaomi:Company {name: "xiaomi", create_at: 1997}) -- node with a node variable name, label, and two properties
# Describing Relationships
Cypher uses a pair of double hyphens (–) to represent an undirected relationship. A directed relationship has an arrow (–> or <–) added to one end. Square bracket notation […] can be used to add details, which may include variables, properties, and/or type information. Here are some common notations for relationships:
--> -- empty relationship
-[role]-> -- empty relationship with only a variable name
-[:WORK]-> -- relationship with a relationship type
-[role:WORK]-> -- relationship with a variable name and relationship type
-[role:WORK {position: "CEO"}]-> -- relationship with a variable name, type, and one property
# Pattern Syntax
The syntax of nodes and relationships mentioned above can be combined to express patterns. Here is a simple pattern as an example:
(leimou:Person {name:"Lei", born:1969})-[:WORK {position:"CEO"}]->
(Xiaomi:Company {name:"Xiaomi Technology Co., Ltd", create_at:2010, tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"})
# Data Types
Cypher supports the following data types: Property types:
- Integer
- String
- Integer Array
- String Array
Structural types:
- Node
- Relationship
- Path
# MATCH Command
The MATCH statement is used to retrieve data from the database based on specified patterns. It is often used together with WHERE statements that have constraints or assertions.
# Finding Nodes
1、Querying all nodes: If there is only one variable in the pattern and no other qualifications, it returns all nodes.
MATCH (n) RETURN n
result:
status:OK,cursor:18,result:10,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
(2)-----------------------------------------------------------------------
ID:1 LABELS:Company PROPS:{name:"Alibaba Group Holdings Limited",create_at:1999.000000,tagline:"Intended to build future commercial infrastructure"}
(3)-----------------------------------------------------------------------
ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(4)-----------------------------------------------------------------------
ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
(5)-----------------------------------------------------------------------
ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000}
(6)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(7)-----------------------------------------------------------------------
ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000}
(8)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000}
(9)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000}
(10)-----------------------------------------------------------------------
ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000}
2、Query all nodes with a specific label, add the :Company label to the nodes in the pattern.
MATCH (n:Company) RETURN n
result:
status:OK,cursor:26,result:3,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
(2)-----------------------------------------------------------------------
ID:1 LABELS:Company PROPS:{name:"Alibaba Group Holdings Limited",create_at:1999.000000,tagline:"Intended to build future commercial infrastructure"}
(3)-----------------------------------------------------------------------
ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
3、Query the node with ID 0.
MATCH (n #0) RETURN n
result:
status:OK,cursor:21,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
# Relationship Lookup:
1、Find relationships based on direction. Relationship direction can be represented by --> or <–. For example, to match all relationships that “Wang” points to from the person node in the pattern, it would be as follows:
MATCH (:Person { name:"Wang" })-->(m) return m
On the contrary, to match all relationships pointing to “Wang”, it would be as follows:
MATCH (:Person { name:"Wang" })<--(m) return m
Since the above two commands do not have any specific conditions on relationships, it will retrieve all relationships pointing out and pointing to “Wang”. 2、Add variables to relationships and return the relationships.
MATCH (:Person { name:"Wang" })-[r]->() return r
result:
status:OK,cursor:48,result:3,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8}
(2)-----------------------------------------------------------------------
ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4}
(3)-----------------------------------------------------------------------
ID:6 HEAD:7 TAIL:2 TYPE:WORK PROPS:{}
3、 Query the relationship with ID 0.
match ()-[r #0]->() return r
result:
status:OK,cursor:28,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"}
4、Match relationship types and query all “friend” relationships.
MATCH (n)-[r:FRIEND]->(m) return n,r,m
result:
status:OK,cursor:38,result:6,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(2)-----------------------------------------------------------------------
ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(3)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000}
(4)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000}
(5)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000} ID:7 HEAD:8 TAIL:3 TYPE:FRIEND PROPS:{weight:2} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
(6)-----------------------------------------------------------------------
ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000} ID:8 HEAD:9 TAIL:3 TYPE:FRIEND PROPS:{weight:1} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
5、Match multiple relationship types and search for relationships of type “friend” or “work”.
match ()-[r:FRIEND|WORK]->() return r
result:
status:OK,cursor:37,result:13,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"}
(2)-----------------------------------------------------------------------
ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10}
(3)-----------------------------------------------------------------------
ID:2 HEAD:4 TAIL:1 TYPE:WORK PROPS:{position:"CEO"}
(4)-----------------------------------------------------------------------
ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"}
(5)-----------------------------------------------------------------------
ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5}
(6)-----------------------------------------------------------------------
ID:1 HEAD:6 TAIL:0 TYPE:WORK PROPS:{position:"staff"}
(7)-----------------------------------------------------------------------
ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8}
(8)-----------------------------------------------------------------------
ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4}
(9)-----------------------------------------------------------------------
ID:6 HEAD:7 TAIL:2 TYPE:WORK PROPS:{}
(10)-----------------------------------------------------------------------
ID:7 HEAD:8 TAIL:3 TYPE:FRIEND PROPS:{weight:2}
(11)-----------------------------------------------------------------------
ID:5 HEAD:8 TAIL:2 TYPE:WORK PROPS:{position:"staff"}
(12)-----------------------------------------------------------------------
ID:8 HEAD:9 TAIL:3 TYPE:FRIEND PROPS:{}
(13)-----------------------------------------------------------------------
ID:3 HEAD:9 TAIL:1 TYPE:WORK PROPS:{position:"staff"}
6、Find relationships with the attribute “position” as “CEO”.
match ()-[r {position:"CEO"}]->() return r
result:
status:OK,cursor:42,result:3,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"}
(2)-----------------------------------------------------------------------
ID:2 HEAD:4 TAIL:1 TYPE:WORK PROPS:{position:"CEO"}
(3)-----------------------------------------------------------------------
ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"}
7、 Find patterns with multiple relationship combinations, i.e., specify the length of relationships. For example, if we search for patterns with two relationships and three node combinations, we call it a pattern with a length of 2.
match (n1)-[r1]->(n2)-[r2]->(n3) return n1,r1,n2,r2,n3
result:
status:OK,cursor:54,result:8,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(2)-----------------------------------------------------------------------
ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(3)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(4)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:1 HEAD:6 TAIL:0 TYPE:WORK PROPS:{position:"staff"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
(5)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(6)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:2 HEAD:4 TAIL:1 TYPE:WORK PROPS:{position:"CEO"} ID:1 LABELS:Company PROPS:{name:"Alibaba Group Holdings Limited",create_at:1999.000000,tagline:"Intended to build future commercial infrastructure"}
(7)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000} ID:7 HEAD:8 TAIL:3 TYPE:FRIEND PROPS:{weight:2} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000} ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
(8)-----------------------------------------------------------------------
ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000} ID:8 HEAD:9 TAIL:3 TYPE:FRIEND PROPS:{} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000} ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
# Path Lookup:
1、Find variable length paths. Find patterns where the relationship length is a minimum of 2, i.e., all relationships with a length greater than or equal to 2 and their start and end nodes.
match (n1:Person{name:"Wang"})-[r*2..]->(n2) return n1,r,n2
result
status:OK,cursor:61,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000} ID:7 HEAD:8 TAIL:3 TYPE:FRIEND PROPS:{weight:2} ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
2、Find patterns where the relationship length is a maximum of 2, i.e., relationships with a length of 1 or 2 and their start and end nodes.
match (n1:Person{name:"Wang"})-[r*..2]->(n2) return n1,r,n2
result
status:OK,cursor:61,result:3,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000} ID:7 HEAD:8 TAIL:3 TYPE:FRIEND PROPS:{weight:2} ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
(2)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000} ID:5 HEAD:8 TAIL:2 TYPE:WORK PROPS:{position:"staff"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(3)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000} ID:7 HEAD:8 TAIL:3 TYPE:FRIEND PROPS:{weight:2} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
>
3、Find all relationships with a specified length of 3 and their start and end nodes.
match (n1)-[r*3..3]->(n2) return n1,r,n2
result:
status:OK,cursor:40,result:2,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(2)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
4、Find patterns where the relationship length is between 2 and 3, and the starting node is the person “Zhang”.
match (n1:Person{name:"Zhang"})-[r*2..3]->(n2) return n1,r,n2
result:
status:OK,cursor:62,result:6,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:1 HEAD:6 TAIL:0 TYPE:WORK PROPS:{position:"staff"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
(2)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:2 HEAD:4 TAIL:1 TYPE:WORK PROPS:{position:"CEO"} ID:1 LABELS:Company PROPS:{name:"Alibaba Group Holdings Limited",create_at:1999.000000,tagline:"Intended to build future commercial infrastructure"}
(3)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(4)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(5)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(6)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
5、Full path query, which searches for all paths between two nodes. This operation often returns a large amount of data due to the Cartesian product of all node relationships in the database, so please use it carefully.
match (n1:Person{name:"Zhang"})-[*]->(n2:Person{name:"Wang"}) return n1,r,n2
Large result sets are not displayed here.
# Optimal Path Lookup:
Optimal paths can be searched for the shortest or longest path and can be searched based on weight or path length. We only need to add a less than or greater than sign after the * in the relationship description in the pattern to represent whether it is searching for the shortest or longest path.
1、Query the shortest professional connection path between “Zhang” and “Zhao”. From the result below, we can see that Zhang is friends with Ma, and Ma is a colleague of Zhao in the same company. Note that we did not specify the arrow direction. ```sql MATCH path=(start :Person{name:"Zhang"})-[rels *<]- (end :Person{name:"Zhao"}) RETURN path ``` result: ``` status:OK,cursor:95,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)----------------------------------------------------------------------- ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:2 HEAD:4 TAIL:1 TYPE:WORK PROPS:{position:"CEO"} ID:1 LABELS:Company PROPS:{name:"Alibaba Group Holdings Limited",create_at:1999.000000,tagline:"Intended to build future commercial infrastructure"} ID:3 HEAD:9 TAIL:1 TYPE:WORK PROPS:{position:"staff"} ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000}
Visualization:
![image](https://neurodb.org/assets/img/zhangzhaolujing.png)
2、Query the longest professional connection path between “Zhang” and “Zhao”.
```sql
MATCH path=(start :Person{name:"Zhang"})-[rels *>]- (end :Person{name:"Zhao"}) RETURN path
The result data is too large to be displayed.
Visualization:
3、Find the shortest path by weight, by accumulating a specific attribute (should be a numerical attribute) on the relationships in the path as the weight of the entire path. This is used to search for the path with the minimum weight, for example, using the weight attribute on the relationship edge to find the shortest path between Ma and Zhang.
MATCH path=(start :Person{name:"Ma"})-[ *<weight]- (end :Person{name:"Zhang"}) RETURN path
result:
status:OK,cursor:97,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4.000000} ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000}
Visualization:
查找Ma与Zhangweight权重的最长路径
MATCH path=(start :Person{name:"Ma"})-[ *>weight]- (end :Person{name:"Zhang"}) RETURN path
result:
status:OK,cursor:97,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10.000000} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5.000000} ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8.000000} ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000}
Visualization:
# RETURN command
The RETURN command is used to return the results matching the variable names and sorts the results by the order of appearance of the variables after RETURN. Variables that are not listed after RETURN will not be returned. In the above example, we have used the RETURN command extensively, so we won’t go into detail here. Example:
match (n1)-[r1]->(n2)-[r2]->(n3) return n1,r1,n2,r2,n3
result:
status:OK,cursor:54,result:8,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(2)-----------------------------------------------------------------------
ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000} ID:4 HEAD:5 TAIL:2 TYPE:WORK PROPS:{position:"CEO"} ID:2 LABELS:Company PROPS:{name:"Baidu Online Network Technology Co., Ltd",create_at:2000.000000,tagline:"It is a leading AI company with a strong internet foundation"}
(3)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:11 HEAD:6 TAIL:5 TYPE:FRIEND PROPS:{weight:5} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(4)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:10 HEAD:7 TAIL:6 TYPE:FRIEND PROPS:{weight:8} ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000} ID:1 HEAD:6 TAIL:0 TYPE:WORK PROPS:{position:"staff"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
(5)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:12 HEAD:4 TAIL:5 TYPE:FRIEND PROPS:{weight:10} ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(6)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000} ID:9 HEAD:7 TAIL:4 TYPE:FRIEND PROPS:{weight:4} ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000} ID:2 HEAD:4 TAIL:1 TYPE:WORK PROPS:{position:"CEO"} ID:1 LABELS:Company PROPS:{name:"Alibaba Group Holdings Limited",create_at:1999.000000,tagline:"Intended to build future commercial infrastructure"}
(7)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000} ID:7 HEAD:8 TAIL:3 TYPE:FRIEND PROPS:{weight:2} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000} ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
(8)-----------------------------------------------------------------------
ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000} ID:8 HEAD:9 TAIL:3 TYPE:FRIEND PROPS:{} ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000} ID:0 HEAD:3 TAIL:0 TYPE:WORK PROPS:{position:"CEO"} ID:0 LABELS:Company PROPS:{name:"Xiaomi Technology Co., Ltd",create_at:2010.000000,tagline:"Committed to enabling everyone around the world to enjoy the beautiful life brought by technology"}
# WHERE command
The WHERE command must be placed after the MATCH command and before the RETURN command. It is used for condition filtering.
1、Single condition query, such as querying people born after 1965.
MATCH (n:Person) where n.born > 1965 return n
result:
status:OK,cursor:45,result:3,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
(2)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(3)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000}
2、Multiple conditions query, such as querying people born after 1965 and whose names start with “L”.
MATCH (n:Person) where n.born > 1965 and n.name =~ "李*" return n
result:
status:OK,cursor:66,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
3、Pattern matching, * matches any number of characters, _ matches a single character, \ is an escape character.
- Match people whose names start with “L” using * for pattern matching.
MATCH (n:Person) where n.name =~ "L*" return n
result:
status:OK,cursor:66,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
- Match people whose names start with “L” using three _ for one Chinese character pattern matching (note: one Chinese character occupies three English spaces).
MATCH (n:Person) where n.name =~ "李___" return n
result:
status:OK,cursor:66,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
- / can escape with * _ / , for example: abc/d can match “abcd”, abc/_d can match “abc_d”, abc//d can match “abc/d”. The command execution is not shown below.
# ORDER BY command
Sort the result set by a certain property of the elements, using asc and desc to specify ascending or descending order. Multiple sorting items can be added after ORDER BY, which will sort the items in multiple sorting criteria in sequence.
MATCH (n:Person) return n order by n.born asc
result
status:OK,cursor:45,result:7,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000}
(2)-----------------------------------------------------------------------
ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000}
(3)-----------------------------------------------------------------------
ID:4 LABELS:Person PROPS:{name:"Ma",born:1964.000000}
(4)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000}
(5)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000}
(6)-----------------------------------------------------------------------
ID:5 LABELS:Person PROPS:{name:"Li",born:1968.000000}
(7)-----------------------------------------------------------------------
ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
# SKIP command
The SKIP command is used to skip a specified number of records in the result set and only return the following records.
MATCH (n:Person) return n skip 5
result
status:OK,cursor:32,result:2,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000}
(2)-----------------------------------------------------------------------
ID:9 LABELS:Person PROPS:{name:"Zhao",born:1952.000000}
# LIMIT command
The LIMIT command is used to limit the number of returned records, returning only the specified number of records from the beginning of the original result set.
MATCH (n:Person) return n limit 1
result:
status:OK,cursor:33,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:3 LABELS:Person PROPS:{name:"Lei",born:1969.000000}
Using the SKIP and LIMIT commands, you can implement paging functionality, such as returning the 3rd page with 3 records per page.
MATCH (n) return n skip 6 limit 3
result:
status:OK,cursor:33,result:3,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
ID:6 LABELS:Person PROPS:{name:"Chen",born:1960.000000}
(2)-----------------------------------------------------------------------
ID:7 LABELS:Person PROPS:{name:"Zhang",born:1967.000000}
(3)-----------------------------------------------------------------------
ID:8 LABELS:Person PROPS:{name:"Wang",born:1965.000000}
# CREATEE command
The CREATE command is used to create graph data based on the pattern expression, which is a collection of nodes and relationships. The pattern expression can be a single node or a combination of nodes and relationships but cannot be a standalone relationship because “hanging” relationships without start or end nodes cannot be created. We have already used the CREATE command in the introductory example above.
1、Create an independent node.
CREATE (Leimou:Person {name:"Zhang", born:1969})
2、Create a relationship with start and end nodes.
CREATE (:Person {name:"Zhang", born:1969})-[:FREND]->(:Person {name:"李四", born:1969})
3、Create a collection of node relationships based on a slightly more complex pattern expression.
CREATE (:Person {name:"Zhang", born:1969})-[:FREND]->(:Person {name:"李四", born:1969})-[:WORK]->(:Company {name:"Xiaomi Technology Co., Ltd", create_at:2010})
# MERGEcommand
The MERGE command is used to search the database for matching data according to the pattern expression like the MATCH command, and if not found, create data according to the pattern expression like the CREATE command. If found, no action is taken.
1、The following command will not modify the database because the nodes described in the pattern already exist.
MERGE (Leimou:Person {name:"Lei", born:1969})
2、The database will still not be modified because there are data that match the pattern.
MERGE (Zhaomou:Person {name:"Zhao", born:1952})-[r:FRIEND]->(Leimou:Person {name:"Lei", born:1969})
3、he following command will create all nodes and relationships described in the pattern because no data matching the pattern is found in the database.
MERGE (Zhaomou:Person {name:"Zhao", born:1952})-[r:LOVE]->(Leimou:Person {name:"Lei", born:1969})
After executing the above commands, there will be two “Zhao” nodes and two “Lei” nodes in the database, but one pair of “Zhao” and “Lei” nodes will be connected by a “LOVE” relationship.
# DELETE command
The DELETE command must come after the MATCH command and is used to delete a specific data item found by the MATCH command, which can be a node or a relationship. If you want to delete a node that still has associated relationships, the DELETE command will fail because we cannot have “hanging” relationships. You need to delete the associated relationships before deleting the node.
1、The following command will prompt that it cannot be deleted because the “Lei” node is still associated with “WORK” and “FRIEND” relationships.
MATCH (Leimou:Person {name:"Wang"}) DELETE Leimou
result:
status:CLIST_HAS_LINK_ERR,cursor:62,result:0,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
2、Delete the “FRIEND” relationship between “Wang” and “Lei”
MATCH (:Person {name:"Wang"})-[r:FRIEND]->(:Person {name:"Wang"}) DELETE r
# DETACH DELETE command
The DETACH DELETE command is similar to the DELETE command and must come after the MATCH command. It is used to delete a specific data item found by the MATCH command, but the DETACH DELETE command will first delete all associated relationships and then delete the node. The DETACH DELETE command can complete these two steps at once, so there will be no situation where it cannot be deleted.
MATCH (Leimou:Person {name:"Lei", born:1969}) DETACH DELETE Leimou
result:
status:OK,cursor:69,result:0,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:1,delete links:0
# SET command
The SET command must come after the MATCH command and is used to set properties for nodes or relationships. If a property with the same name already exists, the SET command will overwrite the original property value; otherwise, a new property will be created.
1、Add the “gender” property to the person “Zhang”.
MATCH (n :Person{name:"Zhang"}) set n.sex="male" return n
2、Modify the “gender” property of the person “Zhang” to “female”.
MATCH (n :Person{name:"Zhang"}) set n.sex="female" return n
3、Modify the “Person” label of the person “Zhang” to “Person2”.
MATCH (n :Person{name:"Zhang"}) set n:Person2 return n
# REMOVE command
The REMOVE command is used to remove properties from nodes or relationships after the MATCH command.
1、Remove the ‘sex’ property from the person ‘Zhang’.
MATCH (n :Person{name:"Zhang"}) REMOVE n.sex return n
2、Remove the ‘Person’ label from the person ‘Zhang’. CALL command
MATCH (n :Person{name:"Zhang"}) REMOVE n:Person return n
# CALLcommand
The CALL command is used to invoke stored procedures within the system, each with its own functionality.
1、db.labels() returns all the node labels in the database.
call db.labels()
result:
tatus:OK,cursor:16,result:2,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
"Person"
(2)-----------------------------------------------------------------------
"Company"
2、db.types() returns all the relationship types in the database.
call db.types()
result:
status:OK,cursor:15,result:2,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
"FRIEND"
(2)-----------------------------------------------------------------------
"WORK"
3、result.count() returns the count of the result set.
match (n) call result.count()
result:
status:OK,cursor:29,result:1,add nodes:0,add links:0,modify nodes:0,modify links:0,delete nodes:0,delete links:0
(1)-----------------------------------------------------------------------
10.000000
# LOAD CSV command
The LOAD CSV command is used to import graph data from a CSV file in bulk. The data source must be a UTF-8 formatted .csv file. You can place the CSV file in the “import” folder in the database’s root directory, so you only need to provide the file name when running the load csv command.
1、Use the CREATE command in conjunction with LOAD CSV to read all rows from “test.csv” and import them as nodes with the first column as the “name” property and the label “Person”. ```sql load csv from "test.csv" as line create (:Person{name:line[1]}) ``` 2、The previous example can also be done with the MERGE command. ```sql load csv from \"test.csv\" as line merge (:Person{name:line[2]})") ``` 3、You can also import and create node labels, relationship types, and properties simultaneously. ```sql load csv from "test.csv" as line create (:line[0]{line[1]:line[2]})" ``` 4、For CSV files with headers, you can use the “load csv with headers” command and append “as line” after the file name to define the variable name for each row. Here, “line” is the variable name, but you can choose any other name. ```sql load csv with headers from \"test.csv\" as line create (:line.label{name:line.name,age:line.age}) ``` 5、You can also use the MATCH command to integrate existing data in the database and create new graph data. ```sql load csv from "test.csv" as line match (n:Person{name:line[2]}) create (n)-[:line[4]{size:line[3]}]->(:Job{name:line[5]}) ``` ## Operations and management
# SAVEDBB command
Since NeuroDB is an in-memory graph database, all data is operated in memory. If you want to persistently save the data to disk as a file, you can use the SAVEDB command. The data will be automatically restored when NeuroDB is started again. It is recommended to run the SAVEDB command after modifying data or before shutting down NeuroDB. Note that if the save-strategy configuration in neuro.conf is set to 1 (automatically save after data changes), there is no need to manually execute the SAVEDB command as the system will automatically execute it.
If the user wants to regularly backup the database, they can utilize the operating system’s scheduled task to periodically copy the neuro.ndb file to another location.
Deleting neuro.ndb will result in all data being cleared.
savedb
# CREATE DATABASE command
NeuroDB supports creating multiple graph databases. By default, when starting NeuroDB, there is a database named “default” available for users. To create a new database, you can use the CREATE DATABASE command followed by the database name.
CREATE DATABASE mydatabase
# SHOW DATABASES command
To view the databases in the system, you can use the SHOW DATABASES command.
SHOW DATABASES
result:
INFO:
default
mydatabase
# USE command
The USE command followed by the database name can be used to switch to a specific database. All subsequent operations will be performed on this database.
USE mydatabase
# DROP DATABASE command
The DROP DATABASE command followed by the database name can be used to delete a specific database. Please use it with caution for data safety.
DROP DATABASE mydatabase
# SHUTDOWN command
The SHUTDOWN command is used to shut down the server-side process. Before shutting down, it will automatically perform persistent storage operations.
SHUTDOWN
# Configuration File
The “neuro.conf” file in the bin directory of the NeuroDB root directory contains system configuration information, with comments for each line of configuration. Users can configure it according to their needs.
# Port number for service startup
port 8839
# Client timeout logout time (in seconds)
max-idletime 300
# Persistence strategy: 0 for manual save, 1 for saving after data changes, 2 for saving when closing the database, 3 for saving when idle (no client connection), 4 for saving at regular intervals (greater than 4, time interval in seconds)
save-strategy 1
# Log level, value range: 0-5, OFF_LEVEL for no logging, ERROR_LEVEL 1 for error, WARNING_LEVEL 2 for warning, INFO_LEVEL 3 for normal messages, DEBUG_LEVEL 4 for debugging, CMD_LEVEL 5 for printing all logs
log-level 4
# Query timeout interruption time (in seconds)
query-timeout 5
# Client Startup Parameters
he NEURO_CLI client connects to the default IP 127.0.0.1 (localhost) on port 8839 by default, which is the default startup port for the NEURO_SERVER service. If you want to modify it, you can use the ip and port parameters.
To connect to a server with IP 192.168.0.1 and startup port 8888, which is the NEURO_SERVER service:
For Windows systems
NEURO_CLI.exe ip 192.168.0.1 port 8888
For Linux systems
./NEURO_CLI ip 192.168.0.1 port 8888
# Runtime Log
In the “neuro.log” file located in the logs directory of the NeuroDB root directory, all running events and command execution records are recorded. We can use the log to view the running records and restore data. Since the log has recorded all executed commands in order, we can restore the data by executing the corresponding commands in sequence.
The contents of neuro.log are as follows:
1671713304:- Server start at localhost:8839
1671713304:- DB loaded from disk
1671713305:. 0 clients connected , 2041914 bytes in use
1671713310:. 0 clients connected , 2041914 bytes in use
1671713311:. Accepted 127.0.0.1:39886
1671713315:. 1 clients connected , 2042131 bytes in use
1671713320:## match (n) return n limit 5
1671713320:. 1 clients connected , 2042398 bytes in use
1671713325:. 1 clients connected , 2042398 bytes in use
1671713330:. 1 clients connected , 2042398 bytes in use
Commands that start with “#” after the timestamp are the executed command records, while others are event records.
# Drivers for various programming languages
# JavaScript Driver
JavaScript Driver Download Link (opens new window) Code example:
import NeuroDBDriver from './neurodb-driver'; // Import the driver package
// Event callback methods
let onOpen = function() {}
let onError = function() {}
let onClose = function() {}
// Create a driver object, pointing to IP: "127.0.0.1", port: 8839
let neurodbBaseAPI = new NeuroDBDriver('127.0.0.1:8839', onOpen, null, onError, onClose);
// Execute a command and return the result set
let resultSet = neurodbBaseAPI.executeQuery("CREATE (n:Person{name:\"test\"}) return n")
// Execute a command
resultSet = neurodbBaseAPI.executeQuery("match (n) return n")
The data structure of the resultSet object is described in the Structure. Driver Object ResultSet Data
# java Driver
Java Driver Download Link (opens new window) Code example::
import org.neurodb.NeuroDBDriver; // Import the driver class
class Test {
public static void main(String[] args) {
try {
// Create a driver object, pointing to IP: "127.0.0.1", port: 8839
NeuroDBDriver neuroDBDriver = new NeuroDBDriver("127.0.0.1", 8839);
// Execute a command and get the ResultSet object
ResultSet resultSet = neuroDBDriver.executeQuery("CREATE (n:Person{name:\"test\"}) return n");
// Execute command example 2
resultSet = neuroDBDriver.executeQuery("match (n) return n");
// It's better to close the driver object if it's no longer used, but keep it open if still in use
neuroDBDriver.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The data structure of the resultSet object is described in the Structure. Driver Object ResultSet Data
# python Driver
Python Driver Download (opens new window) code example:
import NeuroDBDriver # import driver class
# Create a driver object, pointing to IP: "127.0.0.1", port: 8839
driver = NeuroDBDriver("127.0.0.1",8839)
# Execute a command and get the ResultSet object
resultSet=driver.executeQuery("CREATE (n:Person{name:\"test\"}) return ")
# Execute command example 2
resultSet=driver.executeQuery("match (n) return n")
The data structure of the resultSet object is described in the Structure. Driver Object ResultSet Data
# .Net Driver
.Net Driver Download (opens new window) code example
using System;
using NeuroDB_DotNet_Driver;//import driver class
namespace Test
{
class Program
{
static void Main(string[] args)
{
//Create a driver object, pointing to IP: "127.0.0.1", port: 8839
NeuroDBDriver driver = new NeuroDBDriver("127.0.0.1", 8839);
//Execute a command and get the ResultSet object
ResultSet resultSet = driver.executeQuery("CREATE (n:Person{name:\"test\"}) return n");
// Execute command example 2
resultSet = driver.executeQuery("match (n) return n ");
//It's better to close the driver object if it's no longer used, but keep it open if still in use
driver.close();
}
}
}
The data structure of the resultSet object is described in the Structure. Driver Object ResultSet Data
# Go Driver
Go Driver Download (opens new window),support by community contributorWZFlik (opens new window) code example:
package tests
import (
"fmt"
"neurodb.org/neurodb"
"testing"
)
func TestDriver(t *testing.T) {
db, err := neurodb.Open("127.0.0.1", 8839)
if err != nil {
t.Error(err)
}
resultSet ,err := db.ExecuteQuery("match (n) return n")
if err != nil {
t.Error(err)
}
for resultSet.Next() {
fmt.Println(resultSet.Record())
}
resultSet,err = db.ExecuteQuery("match (n)-[r]->(m) return n,r,m")
if err != nil {
t.Error(err)
}
for resultSet.Next() {
fmt.Println(resultSet.Record())
}
}
The data structure of the resultSet object is described in the Structure. Driver Object ResultSet Data
# Dart Driver
Dart Driver Download (opens new window),support by community contributordudu-ltd (opens new window) code example:
import 'package:neurodb_dart_driver/neurodb_dart_driver.dart';
void main() async {
var driver = NeuroDBDriver("127.0.0.1", 8839);
ResultSet resultSet = await driver.executeQuery("match (n) return n");
resultSet = await driver.executeQuery("match (n)-[r]->(m) return n,r,m ");
print("ok");
driver.close();
}
The data structure of the resultSet object is described in the Structure. Driver Object ResultSet Data
# Driver Object ResultSet Data
# RResultSet Return Result Data Structure:
- “cursor”: Pointer to the command execution (if there is a syntax error, the pointer index does not point to the last character)
- “status”: “OK” if the return is successful, otherwise prompt ERROR information
- “msg”: “Execution successful” additional information
- “results”: Number of result records in the result set
- “addNodes”: Number of nodes added
- “addLinks”: Number of relationship edges added
- “modifyNodes”: Number of nodes modified
- “modifyLinks”: Number of relationship edges modified
- “deleteNodes”: Number of nodes deleted
- “deleteLinks”: Number of relationship edges deleted
- “recordSet”: Result set
# “recordSet”: Data structure within the result set:
- “labels”: Set of all node labels in the result set
- “types”: Set of all relationship edge types in the result set
- “keyNames”: Set of property names for all nodes and relationship edges in the result set
- “nodes”: All nodes within the result set
- “links”: All relationship edges within the result set
- “records”: List of result records composed of nodes, relationship edges, and paths arranged in the order of variables after the Return command
# “node” Node data structure
- “id”: Node ID
- “labels”: Array of node labels
- “properties”: List of properties, each property contains the property name and value
# “link” Relationship edge data structure
- “id”: Relationship edge ID
- “hid”: Head node ID
- “tid”: Tail node ID
- “type”: Relationship edge type
- “properties”: List of properties, each property contains the property name and value
# ResultSet Example (Displayed in JSON format)
{
"cursor": 39,
"status": "OK",
"msg": "success",
"results": 1,
"addNodes": 0,
"addLinks": 0,
"modifyNodes": 0,
"modifyLinks": 0,
"deleteNodes": 0,
"deleteLinks": 0,
"recordSet": {
"nodes": [
{
"id": 19,
"labels": [
"staff"
],
"properties": {
"name": "Zhang",
"sex":"male"
}
},
{
"id": 959,
"labels": [
"company"
],
"properties": {
"name": "XX Technology Co"
}
}
],
"links": [
{
"id": 1216,
"hid": 19,
"tid": 959,
"type": "WORK_FOR",
"properties": {}
}
],
"records": [
[
{
"id": 19,
"labels": [
"staff"
],
"properties": {
"name": "Zhang",
"sex":"male"
}
},
{
"id": 1216,
"hid": 19,
"tid": 959,
"type": "WORK_FOR",
"properties": {}
},
{
"id": 959,
"labels": [
"company"
],
"properties": {
"name": "XX Technology Co"
}
}
]
],
"labels": [
"staff",
"company"
],
"types": [
"WORK_FOR"
],
"keyNames": [
"name",
"sex"
]
}
}