Skip to content

Commit

Permalink
update match and return (#1376)
Browse files Browse the repository at this point in the history
* update match and return

* Update 2.match.md

* Update 2.match.md

* Update 2.match.md

* Update docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md

Co-authored-by: abby.huang <78209557+abby-cyber@users.noreply.github.com>

Co-authored-by: abby.huang <78209557+abby-cyber@users.noreply.github.com>
  • Loading branch information
foesa-yang and abby-cyber authored Jan 12, 2022
1 parent f74251d commit 8533feb
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 253 deletions.
317 changes: 69 additions & 248 deletions docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,27 @@ MATCH <pattern> [<clause_1>] RETURN <output> [<clause_2>];

- `output`:定义需要返回的输出。可以使用`AS`设置输出的别名。

!!! compatibility "历史版本兼容性"

从 3.0 版本开始,`pattern`支持同时匹配多个 Tag,所以返回属性时,需要额外指定 Tag 名称。即从`RETURN 变量名.属性名`改为`RETURN 变量名.Tag.属性名`。

- `clause_2`:支持`ORDER BY``LIMIT`子句。

## MATCH 工作流程

1. `MATCH`语句使用原生索引查找起始点或边,起始点或边可以在模式的任何位置。即一个有效的`MATCH`语句,**必须有一个属性、Tag 或 Edge type 已经创建索引,或者在`WHERE`子句中用 id() 函数指定了特定点的 VID**。如何创建索引,请参见[创建原生索引](../14.native-index-statements/1.create-native-index.md)

2. `MATCH`语句在模式中搜索,寻找匹配的边或点。
## 注意事项

!!! note

`MATCH`语句采用的路径类型是`trail`,即遍历时只有点可以重复,边不可以重复。详情请参见[路径](../../1.introduction/2.1.path.md)。

3. `MATCH`语句根据`RETURN`子句检索数据。
!!! compatibility "历史版本兼容性"

## openCypher 兼容性
从 3.0.0 版本开始,`pattern`支持同时匹配多个 Tag,所以返回属性时,需要额外指定 Tag 名称。即从`RETURN 变量名.属性名`改为`RETURN 变量名.Tag.属性名`。

- nGQL 不支持遍历所有点和边,例如`MATCH (v) RETURN v`。但是,建立相应 Tag 的索引后,可以遍历对应 Tag 的所有点,例如`MATCH (v:T1) RETURN v`
- `MATCH`语句中的`WHERE`子句内不支持图模式

- WHERE 子句内不支持图模式
- `MATCH`语句采用的路径类型是`trail`,即遍历时只有点可以重复,边不可以重复。详情请参见[路径](../../1.introduction/2.1.path.md)

## 使用模式(pattern)
- `MATCH`语句中`WHERE`子句使用 id() 函数指定了点的 VID,不需要创建索引即可执行。

### 前提条件
- 当遍历所有点边时,例如`MATCH (v) RETURN v LIMIT <number_rows>`,和当遍历指定 Tag 的点或指定 Edge Type 的边时,例如`MATCH (v:T1) RETURN v LIMIT <number_rows>`,不需要创建索引,但需要使用`LIMIT`限制输出结果数量。

请确保`MATCH`语句有至少一个索引可用,或者其中指定了 VID。如果需要创建索引,但是已经有相关的点、边或属性,用户必须在创建索引后重建索引,索引才能生效。
- 除以上两种情况之外,请确保`MATCH`语句有至少一个索引可用。如果需要创建索引,但是已经有相关的点、边或属性,用户必须在创建索引后重建索引,索引才能生效。如何创建索引,请参见[创建原生索引](../14.native-index-statements/1.create-native-index.md)

!!! caution
## 示例

索引会导致写性能大幅降低(降低 90%甚至更多)。请**不要随意**在生产环境中使用索引,除非很清楚使用索引对业务的影响。
### 创建索引

```ngql
# 在 Tag player 的 name 属性和 Edge type follow 上创建索引。
Expand Down Expand Up @@ -98,25 +86,44 @@ nebula> SHOW JOB 122;

### 匹配点

!!! Compatibility "历史版本兼容性"

在 Nebula Graph 3.0.0 之前,不支持 `MATCH (v) RETURN v`。在 Nebula Graph 3.0.0 开始,支持`MATCH (v) RETURN v`,不需要创建索引,但需要使用 `LIMIT` 限制输出结果数量。

用户可以在一对括号中使用自定义变量来表示模式中的点。例如`(v)`

```ngql
nebula> MATCH (v) \
RETURN v \
LIMIT 3;
+-----------------------------------------------------------+
| v |
+-----------------------------------------------------------+
| ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) |
| ("player106" :player{age: 25, name: "Kyle Anderson"}) |
| ("player115" :player{age: 40, name: "Kobe Bryant"}) |
+-----------------------------------------------------------+
```

### 匹配 Tag

!!! Note
!!! Compatibility "历史版本兼容性"

匹配 Tag 的前提是 Tag 本身有索引或者 Tag 的某个属性有索引,否则,用户无法基于该 Tag 执行 `MATCH` 语句。
在 Nebula Graph 3.0.0 之前,匹配 Tag 的前提是 Tag 本身有索引或者 Tag 的某个属性有索引,否则,用户无法基于该 Tag 执行 `MATCH` 语句。从Nebula Graph 3.0.0 开始,匹配 Tag 可以不创建索引,但需要使用 `LIMIT` 限制输出结果数量

用户可以在点的右侧用`:<tag_name>`表示模式中的 Tag。

```ngql
nebula> MATCH (v:player) \
RETURN v;
+---------------------------------------------------------------+
| v |
+---------------------------------------------------------------+
| ("player105" :player{age: 31, name: "Danny Green"}) |
| ("player109" :player{age: 34, name: "Tiago Splitter"}) |
| ("player111" :player{age: 38, name: "David West"}) |
RETURN v \
LIMIT 3;
+-----------------------------------------------------------+
| v |
+-----------------------------------------------------------+
| ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) |
| ("player106" :player{age: 25, name: "Kyle Anderson"}) |
| ("player115" :player{age: 40, name: "Kobe Bryant"}) |
+-----------------------------------------------------------+
...
```

Expand Down Expand Up @@ -207,7 +214,7 @@ nebula> MATCH (v:player { name: 'Tim Duncan' })--(v2) \

!!! compatibility "历史版本兼容性"

在 nGQL 1.x 中,`--`符号用于行内注释, nGQL 2.x ,`--`符号表示出边或入边,不再用于注释。
在 nGQL 1.x 中,`--`符号用于行内注释, nGQL 2.x ,`--`符号表示出边或入边,不再用于注释。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"})--(v2:player) \
Expand Down Expand Up @@ -305,34 +312,43 @@ nebula> MATCH p=(v:player{name:"Tim Duncan"})-->(v2) \

### 匹配边

除了用`--``-->``<--`表示未命名的边之外,用户还可以在方括号中使用自定义变量命名边。例如`-[e]-`
!!! Compatibility "历史版本兼容性"

在 Nebula Graph 3.0.0 之前,匹配边的前提是边本身有对应属性的索引,否则,用户无法基于边执行 `MATCH` 语句。从 Nebula Graph 3.0.0 开始,匹配边可以不创建索引,但需要使用 `LIMIT` 限制输出结果数量,并且必须指定边的方向。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"})-[e]-(v2) \
RETURN e;
+-----------------------------------------------------------------------+
| e |
+-----------------------------------------------------------------------+
| [:serve "player100"->"team204" @0 {end_year: 2016, start_year: 1997}] |
| [:follow "player101"->"player100" @0 {degree: 95}] |
| [:follow "player102"->"player100" @0 {degree: 75}] |
...
nebula> MATCH ()<-[e]-() \
RETURN e \
LIMIT 3;
+----------------------------------------------------+
| e |
+----------------------------------------------------+
| [:follow "player101"->"player102" @0 {degree: 90}] |
| [:follow "player103"->"player102" @0 {degree: 70}] |
| [:follow "player135"->"player102" @0 {degree: 80}] |
+----------------------------------------------------+
```

### 匹配 Edge type

和点一样,用户可以用`:<edge_type>`表示模式中的 Edge type,例如`-[e:follow]-`

!!! Compatibility "历史版本兼容性"

在 Nebula Graph 3.0.0 之前,匹配 Edge Type 的前提是 Edge type 本身有对应属性的索引,否则,用户无法基于 Edge Type 执行 `MATCH` 语句。从 Nebula Graph 3.0.0 开始,匹配 Edge Type 可以不创建索引,但需要使用 `LIMIT` 限制输出结果数量,并且必须指定边的方向。

```ngql
nebula> MATCH ()-[e:follow]-() \
RETURN e;
+-----------------------------------------------------+
| e |
+-----------------------------------------------------+
| [:follow "player104"->"player105" @0 {degree: 60}] |
| [:follow "player113"->"player105" @0 {degree: 99}] |
| [:follow "player105"->"player100" @0 {degree: 70}] |
...
nebula> MATCH ()-[e:follow]->() \
RETURN e \
limit 3;
+----------------------------------------------------+
| e |
+----------------------------------------------------+
| [:follow "player102"->"player100" @0 {degree: 75}] |
| [:follow "player102"->"player101" @0 {degree: 75}] |
| [:follow "player129"->"player116" @0 {degree: 90}] |
+----------------------------------------------------+
```

### 匹配边的属性
Expand Down Expand Up @@ -501,202 +517,7 @@ nebula> MATCH (v1:player{name:"Tim Duncan"}), (v2:team{name:"Spurs"}) \
+----------------------------------------------------+----------------------------------+
```

## 常用检索操作

### 检索点或边的信息

使用`RETURN {<vertex_name> | <edge_name>}`检索点或边的所有信息。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) \
RETURN v;
+----------------------------------------------------+
| v |
+----------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"}) |
+----------------------------------------------------+
nebula> MATCH (v:player{name:"Tim Duncan"})-[e]->(v2) \
RETURN e;
+-----------------------------------------------------------------------+
| e |
+-----------------------------------------------------------------------+
| [:serve "player100"->"team204" @0 {end_year: 2016, start_year: 1997}] |
| [:follow "player100"->"player101" @0 {degree: 95}] |
| [:follow "player100"->"player125" @0 {degree: 95}] |
+-----------------------------------------------------------------------+
```

### 检索点 ID

使用`id()`函数检索点 ID。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) \
RETURN id(v);
+-------------+
| id(v) |
+-------------+
| "player100" |
+-------------+
```

### 检索 Tag

使用`labels()`函数检索点上的 Tag 列表。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) \
RETURN labels(v);
+------------+
| labels(v) |
+------------+
| ["player"] |
+------------+
```

检索列表`labels(v)`中的第 N 个元素,可以使用`labels(v)[n-1]`。例如下面示例使用`labels(v)[0]`检索第一个元素。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) \
RETURN labels(v)[0];
+--------------+
| labels(v)[0] |
+--------------+
| "player" |
+--------------+
```

### 检索点或边的单个属性

使用`RETURN {<vertex_name> | <edge_name>}.<property>`检索单个属性。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) \
RETURN v.player.age;
+--------------+
| v.player.age |
+--------------+
| 42 |
+--------------+
```

使用`AS`设置属性的别名。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) \
RETURN v.player.age AS Age;
+-----+
| Age |
+-----+
| 42 |
+-----+
```

### 检索点或边的所有属性

使用`properties()`函数检索点或边的所有属性。

```ngql
nebula> MATCH p=(v:player{name:"Tim Duncan"})-[]->(v2) \
RETURN properties(v2);
+----------------------------------+
| properties(v2) |
+----------------------------------+
| {name: "Spurs"} |
| {age: 36, name: "Tony Parker"} |
| {age: 41, name: "Manu Ginobili"} |
+----------------------------------+
```

### 检索 Edge type

使用`type()`函数检索匹配的 Edge type。

```ngql
nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e]->() \
RETURN DISTINCT type(e);
+----------+
| type(e) |
+----------+
| "serve" |
| "follow" |
+----------+
```

### 检索路径

使用`RETURN <path_name>`检索匹配路径的所有信息。

```ngql
nebula> MATCH p=(v:player{name:"Tim Duncan"})-[*3]->() \
RETURN p;
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| p |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})-[:serve@0 {end_year: 2019, start_year: 2015}]->("team204" :team{name: "Spurs"})> |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})-[:serve@0 {end_year: 2015, start_year: 2006}]->("team203" :team{name: "Trail Blazers"})> |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})-[:follow@0 {degree: 75}]->("player101" :player{age: 36, name: "Tony Parker"})> |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
...
```

### 检索路径中的点

使用`nodes()`函数检索路径中的所有点。

```ngql
nebula> MATCH p=(v:player{name:"Tim Duncan"})-[]->(v2) \
RETURN nodes(p);
+---------------------------------------------------------------------------------------------------------------------+
| nodes(p) |
+---------------------------------------------------------------------------------------------------------------------+
| [("player100" :star{} :player{age: 42, name: "Tim Duncan"}), ("player204" :team{name: "Spurs"})] |
| [("player100" :star{} :player{age: 42, name: "Tim Duncan"}), ("player101" :player{name: "Tony Parker", age: 36})] |
| [("player100" :star{} :player{age: 42, name: "Tim Duncan"}), ("player125" :player{name: "Manu Ginobili", age: 41})] |
+---------------------------------------------------------------------------------------------------------------------+
```

### 检索路径中的边

使用`relationships()`函数检索路径中的所有边。

```ngql
nebula> MATCH p=(v:player{name:"Tim Duncan"})-[]->(v2) \
RETURN relationships(p);
+-------------------------------------------------------------------------+
| relationships(p) |
+-------------------------------------------------------------------------+
| [[:serve "player100"->"team204" @0 {end_year: 2016, start_year: 1997}]] |
| [[:follow "player100"->"player101" @0 {degree: 95}]] |
| [[:follow "player100"->"player125" @0 {degree: 95}]] |
+-------------------------------------------------------------------------+
```

### 检索路径长度

使用`length()`函数检索路径的长度。

```ngql
nebula> MATCH p=(v:player{name:"Tim Duncan"})-[*..2]->(v2) \
RETURN p AS Paths, length(p) AS Length;
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+
| Paths | Length |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:serve@0 {end_year: 2016, start_year: 1997}]->("team204" :team{name: "Spurs"})> | 1 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})> | 1 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})> | 1 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("team204" :team{name: "Spurs"})> | 2 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2019, start_year: 2018}]->("team215" :team{name: "Hornets"})> | 2 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 95}]->("player100" :player{age: 42, name: "Tim Duncan"})> | 2 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})> | 2 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})> | 2 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})-[:serve@0 {end_year: 2018, start_year: 2002}]->("team204" :team{name: "Spurs"})> | 2 |
| <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})-[:follow@0 {degree: 90}]->("player100" :player{age: 42, name: "Tim Duncan"})> | 2 |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+
```

### 多MATCH检索
## 多MATCH检索

不同的模式有不同的筛选条件时,可以使用多`MATCH`,会返回模式完全匹配的行。

Expand All @@ -712,7 +533,7 @@ nebula> MATCH (m)-[]->(n) WHERE id(m)=="player100" \
+-------------+-------------+-------------+
```

### OPTIONAL MATCH检索
## OPTIONAL MATCH检索

参见[OPTIONAL MATCH](optional-match.md)

Expand Down
Loading

0 comments on commit 8533feb

Please sign in to comment.