老兵老山兰 發表於 2017-5-24 09:37:00

Neo4j 第三篇:Cypher查询入门

<p>Neo4j使用Cypher查询图形数据,Cypher是描述性的图形查询语言,语法简单,功能强大,由于Neo4j在图形数据库家族中处于绝对领先的地位,拥有众多的用户基数,使得Cypher成为图形查询语言的事实上的标准。本文作为入门级的教程,我不会试图分析Cypher语言的全部内容,本文的目标是循序渐进地使用Cypher语言执行简单的CRUD操作,为了便于演示,本文在Neo4j Browser中执行Cypher示例代码。以下图形包含三个节点和两个关系,本文会一步一步讲解如何利用Cypher语言创建以下图形。</p>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519164108432-1746174343.png" alt=""></p>
<p>&nbsp;</p>
<p>我的Neo4j系列的文章收录在:Neo4j</p>
<p>&nbsp;</p>
<h2><strong>一,easy,热热身</strong></h2>
<p>和SQL很相似,Cypher语言的关键字不区分大小写,但是属性值,标签,关系类型和变量是区分大小写的。</p>
<p><strong>1,变量(Variable)</strong></p>
<p>变量用于对搜索模式的部分进行命名,并在同一个查询中引用,在小括号()中命名变量,<strong>变量名是区分大小写的</strong>,示例代码创建了两个变量:n和b,通过return子句返回变量b;</p>
<div class="cnblogs_code">
<pre>MATCH (n)--&gt;<span>(b)
RETURN b</span></pre>
</div>
<p>在Cypher查询中,变量用于引用搜索模式(Pattern),但是变量不是必需的,如果不需要引用,那么可以忽略变量。</p>
<p><strong>2,访问属性</strong></p>
<p>在Cypher查询中,通过逗号来访问属性,格式是:Variable.PropertyKey,通过id函数来访问实体的ID,格式是id(Variable)。</p>
<div class="cnblogs_code">
<pre>match (n)--&gt;<span style="color: rgba(0, 0, 0, 1)">(b)
</span><span style="color: rgba(0, 0, 255, 1)">where</span> id(n)=<span style="color: rgba(128, 0, 128, 1)">5</span> and b.age=<span style="color: rgba(128, 0, 128, 1)">18</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> b;</pre>
</div>
<h2><strong>二,创建节点</strong></h2>
<p>节点模式的构成:(Variable:Lable1:Lable2{Key1:Value1,Key2,Value2}),实际上,每个节点都有一个整数ID,在创建新的节点时,Neo4j自动为节点设置ID值,在整个数据库中,节点的ID值是递增的和唯一的。</p>
<p>下面的Cypher查询创建一个节点,标签是Person,具有两个属性name和born,通过RETURN子句,返回新建的节点:</p>
<div class="cnblogs_code">
<pre>create (n:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Tom Hanks</span><span style="color: rgba(128, 0, 0, 1)">'</span>, born: <span style="color: rgba(128, 0, 128, 1)">1956</span> }) <span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519164410228-217751375.png" alt=""></p>
<p>继续创建其他节点:</p>
<div class="cnblogs_code">
<pre>create (n:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Robert Zemeckis</span><span style="color: rgba(128, 0, 0, 1)">'</span>, born: <span style="color: rgba(128, 0, 128, 1)">1951</span> }) <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> n;
create (n:Movie { title: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Forrest Gump</span><span style="color: rgba(128, 0, 0, 1)">'</span>, released: <span style="color: rgba(128, 0, 128, 1)">1951</span> }) <span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<h2><strong>三,查询节点</strong></h2>
<p>通过match子句查询数据库,match子句用于指定搜索的模式(Pattern),where子句为match模式增加谓词(Predicate),用于对Pattern进行约束;</p>
<p>1,查询整个图形数据库</p>
<div class="cnblogs_code">
<pre>match(n) <span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p>在图形数据库中,有三个节点,Person标签有连个节点,Movie有1个节点</p>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519164808260-281608105.png" alt=""></p>
<p>点击节点,查看节点的属性,如图,Neo4j自动为节点设置ID值,本例中,Forrest Gump节点的ID值是5,</p>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519164934416-1792994304.png" alt=""></p>
<p><strong>2,查询born属性小于1955的节点</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">match(n)
</span><span style="color: rgba(0, 0, 255, 1)">where</span> n.born&lt;<span style="color: rgba(128, 0, 128, 1)">1955</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519165246369-1977734334.png" alt=""></p>
<p><strong>3,查询具有指定Lable的节点</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">match(n:Movie)
</span><span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519165345447-1527377171.png" alt=""></p>
<p><strong>4,查询具有指定属性的节点</strong></p>
<div class="cnblogs_code">
<pre>match(n{name:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Tom Hanks</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">})
</span><span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519165553353-1221761470.png" alt=""></p>
<h2><strong>四,创建关系</strong></h2>
<p>关系的构成:StartNode <strong>-</strong> <strong>-&gt;</strong> EndNode,在创建关系时,必须指定关系类型。</p>
<p><strong>1,创建没有任何属性的关系</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">MATCH (a:Person),(b:Movie)
WHERE a.name </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Robert Zemeckis</span><span style="color: rgba(128, 0, 0, 1)">'</span> AND b.title = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Forrest Gump</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
CREATE (a)</span>--&gt;<span style="color: rgba(0, 0, 0, 1)">(b)
RETURN r;</span></pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519170338713-1562983462.png" alt=""></p>
<p><strong>2,创建关系,并设置关系的属性</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">MATCH (a:Person),(b:Movie)
WHERE a.name </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Tom Hanks</span><span style="color: rgba(128, 0, 0, 1)">'</span> AND b.title = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Forrest Gump</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
CREATE (a)</span>- }]-&gt;<span style="color: rgba(0, 0, 0, 1)">(b)
RETURN r;</span></pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519170129228-858101407.png" alt=""></p>
<h2><strong>五,查询关系</strong></h2>
<p>在Cypher中,关系分为三种:符号“--”,表示有关系,忽略关系的类型和方向;符号“--&gt;”和“&lt;--”,表示有方向的关系;</p>
<p><strong>1,查询整个数据图形</strong></p>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519170741463-1455419525.png" alt=""></p>
<p><strong>2,查询跟指定节点有关系的节点</strong></p>
<p>示例脚本返回跟Movie标签有关系的所有节点</p>
<div class="cnblogs_code">
<pre>match(n)--<span style="color: rgba(0, 0, 0, 1)">(m:Movie)
</span><span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519170937275-1539723581.png" alt=""></p>
<p><strong>2,查询有向关系的节点</strong></p>
<div class="cnblogs_code">
<pre>MATCH (:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Tom Hanks</span><span style="color: rgba(128, 0, 0, 1)">'</span> })--&gt;<span style="color: rgba(0, 0, 0, 1)">(movie)
RETURN movie;</span></pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519171232978-1077893210.png" alt=""></p>
<p><strong>3,为关系命名,通过为关系定义一个变量名,通过函数type获取关系的类型</strong></p>
<div class="cnblogs_code">
<pre>MATCH (:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Tom Hanks</span><span style="color: rgba(128, 0, 0, 1)">'</span> })--&gt;<span style="color: rgba(0, 0, 0, 1)">(movie)
RETURN r,type(r);</span></pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519171440650-613518319.png" alt=""></p>
<p><strong>4,查询特定的关系类型,通过指定关系的类型和属性</strong></p>
<div class="cnblogs_code">
<pre>MATCH (:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Tom Hanks</span><span style="color: rgba(128, 0, 0, 1)">'</span> })--&gt;<span style="color: rgba(0, 0, 0, 1)">(movie)
RETURN r,type(r);</span></pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519171720932-1997305387.png" alt=""></p>
<h2><strong>六,更新图形</strong></h2>
<p>set子句,用于对更新节点的标签和实体的属性;remove子句用于移除实体的属性和节点的标签;</p>
<p><strong>1,创建一个完整的Path</strong></p>
<p>由于Path是由节点和关系构成的,当路径中的关系或节点不存在时,Neo4j会自动创建;</p>
<div class="cnblogs_code">
<pre>CREATE p =(vic:Worker:Person{ name:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">vic</span><span style="color: rgba(128, 0, 0, 1)">'</span>,title:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Developer</span><span style="color: rgba(128, 0, 0, 1)">"</span> })-[:WORKS_AT]-&gt;(neo)&lt;-[:WORKS_AT]-(michael:Worker:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Michael</span><span style="color: rgba(128, 0, 0, 1)">'</span>,title:<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Manager</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> })
RETURN p</span></pre>
</div>
<p>变量neo代表的节点没有任何属性,但是,其有一个ID值,通过ID值为该节点设置属性和标签</p>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519172644525-1538391137.png" alt=""></p>
<p><strong>2,为节点增加属性</strong></p>
<p>通过节点的ID获取节点,Neo4j推荐通过where子句和ID函数来实现。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">match (n)
</span><span style="color: rgba(0, 0, 255, 1)">where</span> id(n)=<span style="color: rgba(128, 0, 128, 1)">7</span>
<span style="color: rgba(0, 0, 255, 1)">set</span> n.name = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">neo</span><span style="color: rgba(128, 0, 0, 1)">'</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p><strong>3,为节点增加标签</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">match (n)
</span><span style="color: rgba(0, 0, 255, 1)">where</span> id(n)=<span style="color: rgba(128, 0, 128, 1)">7</span>
<span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)"> n:Company
</span><span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519173517119-1418894728.png" alt=""></p>
<p><strong>4,为关系增加属性</strong></p>
<div class="cnblogs_code">
<pre>match (n)&lt;--<span style="color: rgba(0, 0, 0, 1)">(m)
</span><span style="color: rgba(0, 0, 255, 1)">where</span> id(n)=<span style="color: rgba(128, 0, 128, 1)">7</span> and id(m)=<span style="color: rgba(128, 0, 128, 1)">8</span>
<span style="color: rgba(0, 0, 255, 1)">set</span> r.team=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Azure</span><span style="color: rgba(128, 0, 0, 1)">'</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> n;</pre>
</div>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170519174113244-662479972.png" alt=""></p>
<h2>七,跟实体相关的函数</h2>
<p>跟实体相关的函数,主要是获取节点或关系的ID,关系类型,标签和属性等函数。</p>
<p><strong>1,通过id函数,返回节点或关系的ID</strong></p>
<div class="cnblogs_code">
<pre>MATCH (:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Oliver Stone</span><span style="color: rgba(128, 0, 0, 1)">'</span> })--&gt;<span style="color: rgba(0, 0, 0, 1)">(movie)
RETURN id(r);</span></pre>
</div>
<p><strong>2,通过type函数,查询关系的类型</strong></p>
<div class="cnblogs_code">
<pre>MATCH (:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Oliver Stone</span><span style="color: rgba(128, 0, 0, 1)">'</span> })--&gt;<span style="color: rgba(0, 0, 0, 1)">(movie)
RETURN type(r);</span></pre>
</div>
<p><strong>3,通过lables函数,查询节点的标签</strong></p>
<div class="cnblogs_code">
<pre>MATCH (:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Oliver Stone</span><span style="color: rgba(128, 0, 0, 1)">'</span> })--&gt;<span style="color: rgba(0, 0, 0, 1)">(movie)
RETURN lables(movie);</span></pre>
</div>
<p><strong>4,通过keys函数,查看节点或关系的属性键</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">MATCH (a)
WHERE a.name </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Alice</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
RETURN keys(a)</span></pre>
</div>
<p><strong>5,通过properties()函数,查看节点或关系的属性</strong></p>
<div class="cnblogs_code">
<pre>CREATE (p:Person { name: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Stefan</span><span style="color: rgba(128, 0, 0, 1)">'</span>, city: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">Berlin</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)"> })
RETURN properties(p)</span></pre>
</div>
<h2>八,模式</h2>
<p>模式,用于描述如何搜索数据,模式的格式是:使用()标识节点,使用[]标识关系,为了更有效地使用Cypher查询,必须深入理解模式。&nbsp;</p>
<p><strong>1,节点模式</strong></p>
<p>节点具有标签和属性,Cypher为了引用节点,需要给节点命名:</p>
<ul>
<li>(n) :该模式用于描述节点,节点的变量名是n;匿名节点是();</li>
<li>(n:lable):该模式用于描述节点,节点具有特定的标签lable;也可以指定多个标签;</li>
<li>(n{name:"Vic"}):该模式用于描述节点,节点具有name属性,并且name属性值是“Vic”;也可以指定多个属性;</li>
<li>(n:lablle{name:"Vic"}):该模式用于描述节点,节点具有特定的标签和name属性,并且name属性值是“Vic”;</li>
</ul>
<p><strong>2,关系模式</strong></p>
<p>在属性图中,节点之间存在关系,关系通过[]表示,节点之间的关系通过箭头()-[]-&gt;()表示,例如:</p>
<ul>
<li>:该模式用于描述关系,关系的变量名是r;匿名关系是[]</li>
<li>:该模式用于描述关系,关系类型是type;每一个关系必须有且仅有一个类型;</li>
<li>:该模式用于描述关系,关系的类型是type,关系具有属性name,并且name属性值是“Friend”;</li>
</ul>
<p><strong>3,关联节点模式</strong></p>
<p>节点之间通过关系联系在一下,由于关系具有方向性,因此,--&gt;表示存在有向的关系,--表示存在关联,不指定关系的方向,例如:</p>
<ul>
<li>(a)--&gt;(b) :该模式用于描述节点a和b之间存在有向的关系r,</li>
<li>(a)--&gt;(b):该模式用于描述a和b之间存在有向关系;</li>
</ul>
<p><strong>4,变长路径的模式</strong></p>
<p>从一个节点,通过直接关系,连接到另外一个节点,这个过程叫遍历,经过的节点和关系的组合叫做路径(Path),路径是由节点和关系的有序组合。</p>
<ul>
<li>(a)--&gt;(b):是步长为1的路径,节点a和b之间有关系直接关联;</li>
<li>(a)--&gt;()--&gt;(b):是步长为2的路径,从节点a,经过两个关系和一个节点,到达节点b;</li>
</ul>
<p>Cypher语言支持变长路径的模式,变长路径的表示方式是:[*N..M],N和M表示路径长度的最小值和最大值。</p>
<ul>
<li>(a)-[*2]-&gt;(b):表示路径长度为2,起始节点是a,终止节点是b;</li>
<li>(a)-[*3..5]-&gt;(b):表示路径长度的最小值是3,最大值是5,起始节点是a,终止节点是b;</li>
<li>(a)-[*..5]-&gt;(b):表示路径长度的最大值是5,起始节点是a,终止节点是b;</li>
<li>(a)-[*3..]-&gt;(b):表示路径长度的最小值是3,起始节点是a,终止节点是b;</li>
<li>(a)-[*]-&gt;(b):表示不限制路径长度,起始节点是a,终止节点是b;</li>
</ul>
<p><strong>5,路径变量</strong></p>
<p>路径可以指定(assign)给一个变量,该变量是路径变量,用于引用查询路径。</p>
<div class="cnblogs_code">
<pre>p = (a)-[*3..5]-&gt;(b)</pre>
</div>
<p><strong>6,示例</strong></p>
<p>以下示例图有6个节点,每个节点都有一个属性name,节点之间存在关系,关系类型是KNOWS,如图:</p>
<p><img src="https://images2015.cnblogs.com/blog/628084/201705/628084-20170527172242263-445991598.png" alt=""></p>
<p>查询模式是:查找跟Filipa有关系的人,路径长度为1或2,查询的结果是:"Dilshad"和"Anders"</p>
<div class="cnblogs_code">
<pre>MATCH (me)-[:KNOWS*1..2]-(remote_friend)
WHERE me.name = 'Filipa'
RETURN remote_friend.name</pre>
</div>
<h2><strong>&nbsp;</strong></h2>
<p>参考文档:</p>
<p>Chapter 3. Cypher</p>
<p>3.3.16. MERGE</p>
<p>3.2.7. Patterns</p>

</div>
<div id="MySignature" role="contentinfo">
    <div><b>作者</b>:悦光阴</div>
<div><b>出处</b>:http://www.cnblogs.com/ljhdo/</div>
<div>本文版权归作者和博客园所有,欢迎转载,但未经作者同意,必须保留此段声明,且在文章页面醒目位置显示原文连接,否则保留追究法律责任的权利。</div><br><br>
来源:https://www.cnblogs.com/ljhdo/p/5516793.html
頁: [1]
查看完整版本: Neo4j 第三篇:Cypher查询入门