Getting started with Neo4j (2): matching Modes
Announcement: All data comes from the book "Building Web Applications with Python and Neo4j", just for study & not for commerce.
Pattern and Pattern matching are the core of Cypher and describe the shape of the data we want to find, create, or update. If you do not understand the pattern and pattern matching, you cannot write effective and efficient queries.
I. Data Preparation
First, enter the following command to clear the current database:
- Match (n)-[r]-(n1) delete n, r, n1;
- Match (n) delete n
The first command deletes all nodes that are in contact with each other and the second command deletes all independent nodes.
Then, create a bunch of men and women:
- CREATE (bradley: MALE: TEACHER {name: 'bradley ', surname: 'green', age: 24, country: 'us '})
CREATE (matthew: MALE: STUDENT {name: 'Matthew ', surname: 'cooper', age: 36, country: 'use '})
CREATE (lisa: FEMALE {name: 'lisa ', surname: 'adams', age: 15, country: 'Canada '})
CREATE (john: MALE {name: 'john', surname: 'goodman ', age: 24, country: 'Mexico '})
CREATE (annie: FEMALE {name: 'Annie ', surname: 'behr', age: 25, country: 'Canada '})
CREATE (ripley: MALE {name: 'ripley ', surname: 'aniston', country: 'use '})
At this time, there is a node but no contact. The result is as follows:
Then, I entered the following contact statements in a pile and reported an error. But there is no problem with entering one by one:
- MATCH (bradley: MALE {name: "Bradley"}), (matthew: MALE {name: "Matthew"}) WITH bradley, matthew CREATE (bradley )-[: FRIEND]-> (matthew), (bradley)-[: TEACHES]-> (matthew );
- MATCH (bradley: MALE {name: "Bradley"}), (matthew: MALE {name: "Matthew"}) WITH bradley, matthew CREATE (matthew )-[: FRIEND]-> (bradley );
- MATCH (bradley: MALE {name: "Bradley"}), (lisa: FEMALE {name: "Lisa"}) WITH bradley, lisa CREATE (bradley )-[: FRIEND]-> (lisa );
- MATCH (lisa: FEMALE {name: "Lisa"}), (john: MALE {name: "John"}) WITH lisa, john CREATE (lisa )-[: FRIEND]-> (john );
- MATCH (annie: FEMALE {name: "Annie"}), (ripley: MALE {name: "Ripley"}) WITH annie, ripley CREATE (annie )-[: FRIEND]-> (ripley );
- MATCH (ripley: MALE {name: "Ripley"}), (lisa: FEMALE {name: "Lisa"}) WITH ripley, lisa CREATE (ripley )-[: FRIEND]-> (lisa );
Now we can see the appearance of the basic data set:
II. Introduction to models
(1) Pattern for Nodes
Matching nodes is the most basic and simplest one, which is described using parentheses. However, note that if no additional attribute or tag is used, the brackets can be omitted:
- MATCH (a) return
- It is equivalent:
- MATCH a return;
As a result, four nodes are male,
(2) Pattern for Labels
Add ": Tag" to limit the number of tags. It must be noted that multiple tags can be used at the same time to create an intersection. the following second sentence uses multiple tags:
- MATCH (n: MALE) return n;
- MATCH (n: MALE: TEACHER) return n;
Only one node is returned:
(3) Pattern for Relationships
A link is a connection between two given nodes. It can be unidirectional or bidirectional and consists of [] and naming.
Let's look at a one-way example:
- Match (a: TEACHER)-[B: TEACHES]-> (c: STUDENT) return a, B, c
In this example, the system first searches for nodes with the TEACHER and STUDENT labels, and then finds nodes that match the TEACHES.
The two-way query does not require arrows, as shown below:
- Match (a: MALE)-[B: FRIEND]-(c: FEMALE) return a, B, c
(4) Pattern for property
Attribute matching uses curly braces and key-value pairs, which are separated as follows:
- Match (a: MALE {name: "John", age: 24} return
3. Use Where clause
(1) Where
If you only use Pattern and cannot fully meet the requirements, do not force it, there is also Where. You can use the Where clause to further filter data. However, you must note that the Where clause cannot be used independently and can only be used after match, optionalmatch, start, or. For example:
- Match (x)
- Where x. age <30 and x. country = "US"
- Return x
At this time, only one person meets the requirements:
(2) Use Pattern in the Where clause
For a set, if it is an empty set, it indicates false, and if it is not null, it indicates true. You can use the keyword "in" to further limit:
- Match (x)
- Where x. name in ["John", "Andrew"] and x. age is not NULL
- Return x
Of course, you can also use the not and regular expressions for filtering:
- Match (x)
- Where x. name = ~ "J .*"
- Return x
In this case, not = ~ "Xxx", but = ~ "Xxx", that is, = ~ This is a symbol. Do not make any mistakes.
Okay. Here are some tips for this book:
[1] alias:
- With 'age' as haha
- Match (x)
- Where x [toLower (haha)] <30
- Return x
Note: The attribute name in Neo4j is case sensitive. If it is written as x. AGE, the system will prompt that this attribute is not available:
However, "." is not equivalent to "[]". For example, the following statement is incorrect:
Why? I finally found that not "." is not equivalent to "[]", but the two are indeed equal, but the usage is exquisite. For [], it must be a constant, so when I write x [age] as x ['age'], it passes smoothly and returns the result with x. same age:
[2] using the exists () function for Property Verification:
- Match (x)
- Where exists (x. age)
- Return x. name
Previously Used has (), but is now replaced by exists () and removed.
[3] character matching:
This is definitely a powerful tool. It uses starts with, ends with, or contains to match the mode in which the string starts, ends in, or contains. Very convenient! For example:
- Match (x)
- Where x. name starts with "B"
- Return x. name
Or:
- Match (x)
- Where x. name contains ""
- Return x. name
(3) other clauses
[1] order (Ascending by default, mixed sorting is supported)
[2] limit is used to limit the number of returned results, and skip is used to ignore the first one. To use the combination of limit and skip, you can get the Intermediate Value:
- Match (x)
- Return x
- Order by x. age skip 3 limit 2
The returned result is "not the first three, as long as 4th and 5th ". It's really flexible!
(4) with clause
With is also a very useful clause. Before introducing with, you must first study ",". For example, in the following statement, the comma is used as a combination, and the result returns the information of two people x and y, including the comma between x and y in the return statement.
- Match (x {name: "John"}), (y {name: 'Annie '})
- Return x, y
Okay. Continue. For the following initial conditions:
What are the results of executing the following statements?
- Match (x {name: 'lisa '}) <-- (y )--()
- Return count (y)
I think it should be 2, but I am wrong. The result is 4. For example:
Why? That means two indirect connections are counted? Okay, try again. This time we will try it in two directions. The result is still 4:
- Match (x {name: 'lisa '}) -- (y )--()
- Return count (y)
The result of using Brandley is 8, and the result of using a direction is 3. I re-checked all the predefined connections. It should not be 3. Is it a BUG? (Try another version)
OK. Then, let the comma appear in with. The example in the book is as follows:
- Match (x {name: 'bradley '}) -- (y) --> ()
- With y, count (*) AS cnt
- Where cnt> 1
- Return y
The returned value is Matthew, Which is OK. Because of all the records that match the pattern, only Matthew has more than two connections. The question is, do I have to write with y to limit it? What if I remove y?
- Match (x {name: 'bradley '}) -- (y) --> ()
- With count (*) AS cnt
- Where cnt> 1
- Return cnt
The value of cnt is changed to 3. OK. I will add y to check the value of cnt:
- Match (x {name: 'bradley '}) -- (y) --> ()
- With y, count (*) AS cnt
- Where cnt> 1
- Return cnt
In this case, the returned cnt is 2. The above attempt fully demonstrates that in the with y, xxx mode, the y before the comma serves as a limitation. If y is not added, then:
- Match (x {name: 'bradley '}) -- (y) --> ()
- Return count (*)
The number of records is 3, indicating the three links and Their nodes that are hit by Bradley. If the inference is correct, add a z to indicate the target node, then count (z) there should be two:
- Match (x {name: 'bradley '}) -- (y) --> (z)
- Return count (z)
The result is 3, but if I add distinct, it is changed to 2:
- Match (x {name: 'bradley '}) -- (y) --> (z)
- Return count (distinct z)
I understand, some of them have repeated computation. Now let's try the uncertain examples:
That is to say, it is correct to add distinct to the contact result. If distinct is not added, it is 4 and 2. When you do not contact me, you will see the ghost:
What's even more strange is that the following result does not return John:
Oh, my God. I finally found out what's going on. It's all my fault! I don't know much about it.
For more information, I have always considered (x) -- (y) -- () as a group of contacts. In fact, this is incorrect because the contact is not represented, it is represented. Check whether there is any direction or no direction. This is all right:
Now, let's look at the combination of the brackets. Then I will try-instead of-, such:
Obviously, the result is incorrect. That is to say, match (x {name: 'lisa '})-(y)-(z) is incorrect. Of course, if you change to --, there is no syntax error: match (x {name: 'lisa '}) -- (y) -- (z) return count (*), but the result is 4. Now I understand that because (a) -- (B) -- (c) represents the connection relationship between nodes, that is, to ensure that a is Lisa and B is connected to, and c must be connected to B. In layman's terms, a is centered on a and expanded to 2 layers. If I understand it right, match (x {name: 'lisa '}) -- (y) -- (z) return z, the result should be the two nodes at the outermost layer. And match (x {name: 'lisa '}) -- (y) return count (*) should be directly connected to Lisa's three nodes. Try and verify:
Congratulations! although it took a long time, we finally got it done! On the other hand, you can also do this for your contact: [a]-(B)-[c]. I didn't try it, but I believe it works. Cypher is really flexible!
Then, use with x to add conditions for creation. However, no matter whether or not this with x is the same, three kai instances are created:
(5) union and union all clauses
Similar to SQL, union is used to connect two matches. duplicate records are excluded from the returned results. However, union all functions are the same, but duplicate records are not excluded.
- Match (x: MALE)-[: FRIEND]-> () return x. name, labels (x)
- Union
- Match (x: FEMALE)-[: FRIEND]-> () return x. name, labels (x)
Labels () returns all tags, as shown in the following figure:
However, note that no label () is returned.
This blog post is a longer one and has finally come to an end. Next, we will start article 3.
Wuyue's Summit
May 23, 2017 (memphtan time)
20: 37
Final draft in Dorsey