Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update match and return #1376

Merged
merged 5 commits into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
314 changes: 71 additions & 243 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 @@ -26,33 +26,28 @@ MATCH <pattern> [<clause_1>] RETURN <output> [<clause_2>];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

23行的历史兼容也放到注意事项一节

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

## MATCH 工作流程
## 注意事项

1. `MATCH`语句使用原生索引查找起始点或边,起始点或边可以在模式的任何位置。即一个有效的`MATCH`语句,**必须有一个属性、Tag 或 Edge type 已经创建索引,或者在`WHERE`子句中用 id() 函数指定了特定点的 VID**。如何创建索引,请参见[创建原生索引](../14.native-index-statements/1.create-native-index.md)。
- 除以下两种情况之外,请确保`MATCH`语句有至少一个索引可用。如果需要创建索引,但是已经有相关的点、边或属性,用户必须在创建索引后重建索引,索引才能生效。如何创建索引,请参见[创建原生索引](../14.native-index-statements/1.create-native-index.md)。

2. `MATCH`语句在模式中搜索,寻找匹配的边或点。
- 遍历所有点和边,例如`MATCH (v) RETURN v`和遍历对应 Tag 的所有点,例如`MATCH (v:T1) RETURN v`,不需要创建索引,但需要**使用`LIMIT`限制输出结果数量**。
- **在`WHERE`子句中用 id() 函数指定了点的 VID**,不需要创建索引。
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

!!! note

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

3. `MATCH`语句根据`RETURN`子句检索数据。
!!! caution

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

- nGQL 不支持遍历所有点和边,例如`MATCH (v) RETURN v`。但是,建立相应 Tag 的索引后,可以遍历对应 Tag 的所有点,例如`MATCH (v:T1) RETURN v`
- `MATCH`语句在模式中搜索,寻找匹配的边或点
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

- WHERE 子句内不支持图模式。

## 使用模式(pattern)
!!! note

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

请确保`MATCH`语句有至少一个索引可用,或者其中指定了 VID。如果需要创建索引,但是已经有相关的点、边或属性,用户必须在创建索引后重建索引,索引才能生效
- `MATCH`语句根据`RETURN`子句检索数据,`WHERE`子句内不支持图模式
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

!!! caution
## 示例

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

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

### 匹配点

!!! Compatibility

在 Nebula Graph {{nebula.release}} 之前,不支持 `MATCH (v) RETURN v`。在 Nebula Graph {{nebula.release}} 之后,支持`MATCH (v) RETURN v`,不需要创建索引,但需要使用 `LIMIT` 限制输出结果数量。
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

用户可以在一对括号中使用自定义变量来表示模式中的点。例如`(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
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

匹配 Tag 的前提是 Tag 本身有索引或者 Tag 的某个属性有索引,否则,用户无法基于该 Tag 执行 `MATCH` 语句
在 Nebula Graph {{nebula.release}} 之前,匹配 Tag 不需要使用 `LIMIT` 限制输出结果数量,且匹配点的属性的前提是 Tag 本身有对应属性的索引。在 Nebula Graph {{nebula.release}} 之后,匹配 Tag 不需要创建索引,需要使用 `LIMIT` 限制输出结果数量
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

用户可以在点的右侧用`:<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 +221,7 @@ nebula> MATCH (v:player { name: 'Tim Duncan' })--(v2) \

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

在 nGQL 1.x 中,`--`符号用于行内注释,在 nGQL 2.x ,`--`符号表示出边或入边,不再用于注释。
在 nGQL 1.x 中,`--`符号用于行内注释,在 nGQL 2.x ,`--`符号表示出边或入边,不再用于注释。
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

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

### 匹配边

除了用`--`、`-->`、`<--`表示未命名的边之外,用户还可以在方括号中使用自定义变量命名边。例如`-[e]-`。
!!! Compatibility
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

在 Nebula Graph {{nebula.release}} 之前,匹配边不需要使用 `LIMIT` 限制输出结果数量,且匹配边的前提是边本身有对应属性的索引。在 Nebula Graph {{nebula.release}} 之后,匹配边不需要创建索引,但需要使用 `LIMIT` 限制输出结果数量,并且不支持双向边。
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

```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
foesa-yang marked this conversation as resolved.
Show resolved Hide resolved

在 Nebula Graph {{nebula.release}} 之前,匹配边不需要使用 `LIMIT` 限制输出结果数量,且匹配边的前提是边本身有对应属性的索引。在 Nebula Graph {{nebula.release}} 之后,匹配边不需要创建索引,需要使用 `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 +524,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 +540,7 @@ nebula> MATCH (m)-[]->(n) WHERE id(m)=="player100" \
+-------------+-------------+-------------+
```

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

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

Expand Down
Loading