ZhangZhihui's Blog  

Built-in databases in Neo4j

All Neo4j servers contain a built-in database called system, which behaves differently than all other databases. The system database stores system data and you can not perform graph queries against it.

A fresh installation of Neo4j includes two databases:

  • system - the system database described above, containing meta-data on the DBMS and security configuration.

  • neo4j - the default database, named using the config option dbms.default_database=neo4j.

 

Query considerations

Most of the time Cypher queries are reading or updating queries, which are run against a graph. There are also administrative commands that apply to a database, or to the entire DBMS. Administrative commands cannot be run in a session connected to a normal user database, but instead need to be run within a session connected to the system database. Administrative commands execute on the system database. If an administrative command is submitted to a user database, it is rerouted to the system database.

 

Cypher and Neo4j transactions

All Cypher queries run within transactions. Modifications done by updating queries are held in memory by the transaction until it is committed, at which point the changes are persisted to disk and become visible to other transactions. If an error occurs - either during query evaluation, such as division by zero, or during commit, such as constraint violations - the transaction is automatically rolled back, and no changes are persisted in the graph.

In short, an updating query always either fully succeeds or does not succeed at all.

 

Explicit and implicit transactions

Transactions in Neo4j can be either explicit or implicit.

ExplicitImplicit

Opened by the user.

Opened automatically.

Can execute multiple Cypher queries in sequence.

Can execute a single Cypher query.

Committed, or rolled back, by the user.

Committed automatically when a transactions finishes successfully.

Queries that start separate transactions themselves, such as queries using CALL { ... } IN TRANSACTIONS, are only allowed in implicit mode. Explicit transactions cannot be managed directly from queries, they must be managed via APIs or tools.

 

DBMS transactions

Beginning a transaction while connected to a DBMS will start a DBMS-level transaction. A DBMS-level transaction is a container for database transactions.

A database transaction is started when the first query to a specific database is issued. Database transactions opened inside a DBMS-level transaction are committed or rolled back when the DBMS-level transaction is committed or rolled back.

DBMS transactions have the following limitations:

  • Only one database can be written to in a DBMS transaction.

  • Cypher operations fall into the following main categories:

    • Operations on graphs.

    • Schema commands.

    • Administration commands.

It is not possible to combine any of these workloads in a single DBMS transaction.

 

ACID compliance

Neo4j is fully ACID compliant. This means that:

  • Atomicity - If a part of a transaction fails, the database state is left unchanged.

  • Consistency — Every transaction leaves the database in a consistent state.

  • Isolation — During a transaction, modified data cannot be accessed by other operations.

  • Durability — The DBMS can always recover the results of a committed transaction.

 

Core concepts

Nodes

MATCH (n:Person {name:'Anna'})
RETURN n.born AS birthYear

 

Relationships

MATCH (:Person {name: 'Anna'})-[r:KNOWS WHERE r.since < 2020]->(friend:Person)
RETURN count(r) As numberOfFriends

 

Paths

MATCH (n:Person {name: 'Anna'})-[:KNOWS]-{1,5}(friend:Person WHERE n.born < friend.born)
RETURN DISTINCT friend.name AS olderConnections

This example uses a quantified relationship to find all paths up to 5 hops away。

Paths can also be assigned variables. For example, the below query binds a whole path pattern, which matches the SHORTEST path from Anna to another Person node in the graph with a nationality property set to Canadian. In this case, the RETURN clause returns the full path between the two nodes.

MATCH p = SHORTEST 1 (:Person {name: 'Anna'})-[:KNOWS]-+(:Person {nationality: 'Canadian'})
RETURN p

 

 

The below query searches the graph for outgoing relationships from the Tom Hanks node to any Movie nodes, and returns the relationships and the titles of the movies connected to him.

MATCH (tom:Person {name:'Tom Hanks'})-[r]->(m:Movie)
RETURN type(r) AS type, m.title AS movie

 

The below query uses a NOT label expression (!) to return all relationships connected to Tom Hanks that are not of type ACTED_IN.

MATCH (:Person {name:'Tom Hanks'})-[r:!ACTED_IN]->(m:Movie)
Return type(r) AS type, m.title AS movies

 

Finding paths

To search for patterns of a fixed length, specify the distance (hops) between the nodes in the pattern by usingquantifier ({n}).

For example, the following query matches all Person nodes exactly 2 hops away from Tom Hanks and returns the first five rows. 

MATCH (tom:Person {name:'Tom Hanks'}) -- {2} (colleagues:Person)
RETURN DISTINCT colleagues.name AS name, colleagues.born AS bornIn
ORDER BY bornIn
LIMIT 5

 

It is also possible to match a graph for patterns of a variable length. The below query matches all Person nodes between 1 and 4 hops away from Tom Hanks and returns the first five rows.

MATCH (p:Person {name:'Tom Hanks'}) -- {1,4} (colleagues:Person)
RETURN DISTINCT colleagues.name AS name, colleagues.born AS bornIn
ORDER BY bornIn, name
LIMIT 5

 

 

The SHORTEST keyword can be used to find a variation of the shortest paths between two nodes. In this example, ALL SHORTEST paths between the two nodes Keanu Reeves and Tom Cruise are found.

The count() function calculates the number of these shortest paths.

The length() function calculates the length of each path in terms of traversed relationships.

 

 

Finding recommendations

The following query tries to recommend co-actors for Keanu Reeves, who he has yet to work with but who his co-actors have worked with. The query then orders the results by how frequently a matched co-co-actor has collaborated with one of Keanu Reeves' co-actors.

MATCH (keanu:Person {name: "Keanu Reeves"}) - [:ACTED_IN] -> (m1:Movie) <- [:ACTED_IN] - (coActors:Person),
      (coActors:Person) - [:ACTED_IN] -> (m2:Movie) <- [:ACTED_IN] - (coCoActors:Person)
WHERE NOT (keanu) - [:ACTED_IN] -> () <- [:ACTED_IN] - (coCoActors) AND keanu <> coCoActors
RETURN coCoActors.name AS recomended, count(coCoActors) AS strength
ORDER BY strength DESC
LIMIT 7

 

复制代码
╒═════════════════╤════════╕
│recomended       │strength│
╞═════════════════╪════════╡
│"Tom Hanks"      │4       │
├─────────────────┼────────┤
│"Natalie Portman"│3       │
├─────────────────┼────────┤
│"Stephen Rea"    │3       │
├─────────────────┼────────┤
│"John Hurt"      │3       │
├─────────────────┼────────┤
│"Halle Berry"    │3       │
├─────────────────┼────────┤
│"Jim Broadbent"  │3       │
├─────────────────┼────────┤
│"Ben Miles"      │3       │
└─────────────────┴────────┘
复制代码

 

There are several connections between the Keanu Reeves and Tom Hanks nodes in the movie database, but the two have never worked together in a film. The following query matches coactors who could introduce the two, by looking for co-actors who have worked with both of them in separate movies:

MATCH (keanu:Person {name: "Keanu Reeves"}) - [:ACTED_IN] -> (:Movie) <- [:ACTED_IN] - (coActors:Person),
      (tom:Person {name: "Tom Hanks"}) - [:ACTED_IN] -> (:Movie) <- [:ACTED_IN] - (coActors:Person)
RETURN coActors.name AS coActors, count(coActors) AS strength
ORDER BY strength DESC

 

╒═════════════════╤════════╕
│coActors         │strength│
╞═════════════════╪════════╡
│"Hugo Weaving"   │3       │
├─────────────────┼────────┤
│"Charlize Theron"│1       │
└─────────────────┴────────┘

 

Cypher expressions

General

  • A variable: nxrelmyFancyVariable`A name with special characters in it[]!`.

  • A property: n.propx.proprel.thisPropertymyFancyVariable.`(special property name)`.

  • A dynamic property: n["prop"]rel[n.city + n.zip]map[coll[0]].

  • A parameter: $param$0.

  • A list of expressions: ['a', 'b'][1, 2, 3]['a', 2, n.property, $param][].

  • A function call: length(p)nodes(p).

  • An aggregate function call: avg(x.prop)count(*).

  • A path-pattern: (a)-[r]->(b)(a)-[r]-(b)(a)--(b)(a)-->()<--(b).

  • An operator application: 1 + 23 < 4.

  • A subquery expression: COUNT {}COLLECT {}EXISTS {}CALL {}.

  • A regular expression: a.name =~ 'Tim.*'.

  • CASE expression.

  • null.

 

 

String literal escape sequences

String literals can contain the following escape sequences:

Escape sequenceCharacter

\t

Tab

\b

Backspace

\n

Newline

\r

Carriage return

\f

Form feed

\'

Single quote

\"

Double quote

\\

Backslash

\uxxxx

Unicode UTF-16 code point (4 hex digits must follow the \u)

 

Conditional expressions (CASE)

Generic conditional expressions can be expressed in Cypher® using the CASE construct. Two variants of CASE exist within Cypher: the simple form, to compare a single expression against multiple values, and the generic form, to express multiple conditional statements.

 

复制代码
CREATE
  (alice:Person {name:'Alice', age: 38, eyes: 'brown'}),
  (bob:Person {name: 'Bob', age: 25, eyes: 'blue'}),
  (charlie:Person {name: 'Charlie', age: 53, eyes: 'green'}),
  (daniel:Person {name: 'Daniel', eyes: 'brown'}),
  (eskil:Person {name: 'Eskil', age: 41, eyes: 'blue'}),
  (alice)-[:KNOWS]->(bob),
  (alice)-[:KNOWS]->(charlie),
  (bob)-[:KNOWS]->(daniel),
  (charlie)-[:KNOWS]->(daniel),
  (bob)-[:MARRIED]->(eskil)
复制代码

 

Simple CASE

The simple CASE form is used to compare a single expression against multiple values, and is analogous to the switch construct of programming languages. The expressions are evaluated by the WHEN operator until a match is found. If no match is found, the expression in the ELSE operator is returned. If there is no ELSE case and no match is found, null will be returned.

Syntax

CASE test
  WHEN value [, value]* THEN result
  [WHEN ...]
  [ELSE default]
END

Example

MATCH (n:Person)
RETURN
CASE n.eyes
  WHEN 'blue'  THEN 1
  WHEN 'brown', 'hazel' THEN 2
  ELSE 3
END AS result, n.eyes

 

Extended SimpleCASE

The extended simple CASE form allows the comparison operator to be specified explicitly. The simple CASE uses an implied equals (=) comparator.

The supported comparators are:

Syntax

CASE test
  WHEN [comparisonOperator] value [, [comparisonOperator] value ]* THEN result
  [WHEN ...]
  [ELSE default]
END

Example

复制代码
MATCH (n:Person)
RETURN n.name,
CASE n.age
  WHEN IS NULL, IS NOT TYPED INTEGER | FLOAT THEN "Unknown"
  WHEN = 0, = 1, = 2 THEN "Baby"
  WHEN <= 13 THEN "Child"
  WHEN < 20 THEN "Teenager"
  WHEN < 30 THEN "Young Adult"
  WHEN > 1000 THEN "Immortal"
  ELSE "Adult"
END AS result
复制代码

 

Generic CASE

The generic CASE expression supports multiple conditional statements, and is analogous to the if-elseif-else construct of programming languages. Each row is evaluated in order until a true value is found. If no match is found, the expression in the ELSE operator is returned. If there is no ELSE case and no match is found, null will be returned.

Syntax

CASE
  WHEN predicate THEN result
  [WHEN ...]
  [ELSE default]
END

Example

MATCH (n:Person)
RETURN
CASE
  WHEN n.eyes = 'blue' THEN 1
  WHEN n.age < 40      THEN 2
  ELSE 3
END AS result, n.eyes, n.age

 

CASE with null values

When working with null values, you may be forced to use the generic CASE form. The two examples below use the age property of the Daniel node (which has a null value for that property) to clarify the difference.

Simple CASE
MATCH (n:Person)
RETURN n.name,
CASE n.age
  WHEN null THEN -1
  ELSE n.age - 10
END AS age_10_years_ago

 

复制代码
╒═════════╤════════════════╕
│n.name   │age_10_years_ago│
╞═════════╪════════════════╡
│"Alice"  │28              │
├─────────┼────────────────┤
│"Bob"    │15              │
├─────────┼────────────────┤
│"Charlie"│43              │
├─────────┼────────────────┤
│"Daniel" │null            │
├─────────┼────────────────┤
│"Eskil"  │31              │
└─────────┴────────────────┘
复制代码

 

Generic CASE

MATCH (n:Person)
RETURN n.name,
CASE
  WHEN n.age IS NULL THEN -1
  ELSE n.age - 10
END AS age_10_years_ago

 

复制代码
╒═════════╤════════════════╕
│n.name   │age_10_years_ago│
╞═════════╪════════════════╡
│"Alice"  │28              │
├─────────┼────────────────┤
│"Bob"    │15              │
├─────────┼────────────────┤
│"Charlie"│43              │
├─────────┼────────────────┤
│"Daniel" │-1              │
├─────────┼────────────────┤
│"Eskil"  │31              │
└─────────┴────────────────┘
复制代码

 

CASE expressions and succeeding clauses

The results of a CASE expression can be used to set properties on a node or relationship.

 

复制代码
MATCH (n:Person)
WITH n,
CASE n.eyes
  WHEN 'blue'  THEN 1
  WHEN 'brown' THEN 2
  ELSE 3
END AS colorCode
SET n.colorCode = colorCode
RETURN n.name, n.colorCode
复制代码

 

Further considerations

CASE result branches are statically checked prior to execution. This means that if a branch is not semantically correct, it will still throw an exception, even if that branch may never be executed during runtime.

In the following example, date is statically known to be a STRING value, and therefore would fail if treated as a DATE value.

Not allowed

WITH "2024-08-05" AS date, "string" AS type
RETURN CASE type
    WHEN "string" THEN datetime(date)
    WHEN "date" THEN datetime({year: date.year, month: date.month, day: date.day})
    ELSE datetime(date)
END AS dateTime

 

ERROR: Neo.ClientError.Statement.SyntaxError

Type mismatch: expected Map, Node, Relationship, Point, Duration, Date, Time, LocalTime, LocalDateTime or DateTime but was String (line 4, column 38 (offset: 136))
"    WHEN "date" THEN datetime({year: date.year, month: date.month, day: date.day})"

 

Clauses

Reading clauses

ClauseDescription

MATCH

Specify the patterns to search for in the database.

OPTIONAL MATCH

Specify the patterns to search for in the database while using nulls for missing parts of the pattern.

Reading sub-clauses

These comprise sub-clauses that must operate as part of reading clauses.

Sub-clauseDescription

WHERE

Adds constraints to the patterns in a MATCH or OPTIONAL MATCH clause or filters the results of a WITH clause.

ORDER BY [ASC[ENDING] | DESC[ENDING]]

A sub-clause following RETURN or WITH, specifying that the output should be sorted in either ascending (the default) or descending order. As of Neo4j 5.24, it can also be used as a standalone clause.

SKIP / OFFSET

Defines from which row to start including the rows in the output. As of Neo4j 5.24, it can be used as a standalone clause.

LIMIT

Constrains the number of rows in the output. As of Neo4j 5.24, it can be used as a standalone clause.

Projecting clauses

These comprise clauses that define which expressions to return in the result set. The returned expressions may all be aliased using AS.

ClauseDescription

RETURN …​ [AS]

Defines what to include in the query result set.

WITH …​ [AS]

Allows query parts to be chained together, piping the results from one to be used as starting points or criteria in the next.

UNWIND …​ [AS]

Expands a list into a sequence of rows.

FINISH

Defines a query to have no result.

Writing clauses

These comprise clauses that write the data to the database.

ClauseDescription

CREATE

Create nodes and relationships.

DELETE

Delete nodes, relationships or paths. Any node to be deleted must also have all associated relationships explicitly deleted.

DETACH DELETE

Delete a node or set of nodes. All associated relationships will automatically be deleted.

SET

Update labels on nodes and properties on nodes and relationships.

REMOVE

Remove properties and labels from nodes and relationships.

FOREACH

Update data within a list, whether components of a path, or the result of aggregation.

Reading/Writing clauses

These comprise clauses that both read data from and write data to the database.

ClauseDescription

MERGE

Ensures that a pattern exists in the graph. Either the pattern already exists, or it needs to be created.

--- ON CREATE

Used in conjunction with MERGE, this write sub-clause specifies the actions to take if the pattern needs to be created.

--- ON MATCH

Used in conjunction with MERGE, this write sub-clause specifies the actions to take if the pattern already exists.

CALL …​ [YIELD …​ ]

Invokes a procedure deployed in the database and return any results.

Subquery clauses

ClauseDescription

CALL { …​ }

Evaluates a subquery, typically used for post-union processing or aggregations.

CALL { …​ } IN TRANSACTIONS

Evaluates a subquery in separate transactions. Typically used when modifying or importing large amounts of data.

Set operations

ClauseDescription

UNION

Combines the result of multiple queries into a single result set. Duplicates are removed.

UNION ALL

Combines the result of multiple queries into a single result set. Duplicates are retained.

Multiple graphs

ClauseDescription

USE

Determines which graph a query, or query part, is executed against.

Importing data

ClauseDescription

LOAD CSV

Use when importing data from CSV files.

CALL { …​ } IN TRANSACTIONS

This clause may be used to prevent an out-of-memory error from occurring when importing large amounts of data using LOAD CSV.

Listing functions and procedures

ClauseDescription

SHOW FUNCTIONS

List the available functions.

SHOW PROCEDURES

List the available procedures.

Configuration Commands

ClauseDescription

SHOW SETTINGS

List configuration settings.

Transaction Commands

ClauseDescription

SHOW TRANSACTIONS

List the available transactions.

TERMINATE TRANSACTIONS

Terminate transactions by their IDs.

Reading hints

These comprise clauses used to specify planner hints when tuning a query. More details regarding the usage of these — and query tuning in general — can be found in Planner hints and the USING keyword.

HintDescription

USING INDEX

Index hints are used to specify which index, if any, the planner should use as a starting point.

USING INDEX SEEK

Index seek hint instructs the planner to use an index seek for this clause.

USING SCAN

Scan hints are used to force the planner to do a label scan (followed by a filtering operation) instead of using an index.

USING JOIN

Join hints are used to enforce a join operation at specified points.

Index and constraint clauses

These comprise clauses to create, show, and drop indexes and constraints.

ClauseDescription

CREATE | SHOW | DROP INDEX

Create, show or drop an index.

CREATE | SHOW | DROP CONSTRAINT

Create, show or drop a constraint.

Administration clauses

Cypher includes commands to manage databases, aliases, servers, and role-based access control. To learn more about each of these, see:

 

posted on   ZhangZhihuiAAA  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2024-02-15 Go - map
2024-02-15 Go 100 mistakes - #26: Slices and memory leaks
2024-02-15 Go 100 mistakes - #25: Unexpected side effects using slice append
2024-02-15 Go 100 mistakes - #21: Inefficient slice initialization
2024-02-15 Go - slice
 
点击右上角即可分享
微信分享提示