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

Implement the multi query parts of openCypher #1355

Merged
Show file tree
Hide file tree
Changes from 2 commits
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
2 changes: 1 addition & 1 deletion docs-2.0/2.quick-start/6.cheatsheet-for-ngql-command.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@



* [UNWIND](../3.ngql-guide/7.general-query-statements/7.unwind.md)
* [UNWIND](../3.ngql-guide/8.clauses-and-options/unwind.md)

```
UNWIND <list> AS <alias> <RETURN clause>
Expand Down
2 changes: 1 addition & 1 deletion docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ nebula> CREATE TAG IF NOT EXISTS player(name string, age int);
|相等运算符| `=` | `==` |
|数学求幂| `^` | 使用`pow(x, y)`替代`^`。 |
|边 Rank| 无此概念 | 用`@rank`设置。 |
|语句|-|不支持 openCypher 9 的所有 DML 语句(如`CREATE`、`MERGE`等),不支持所有的 DCL, 和支持部分 `MATCH` 语法和函数(不支持`OPTIONAL MATCH`,不支持多`MATCH`,不支持 `WHERE` 中使用图 pattern)。 |
|语句|-|不支持 openCypher 9 的所有 DML 语句(如`CREATE`、`MERGE`等),不支持所有的 DCL, 和支持部分 `MATCH` 语法和函数(不支持 `WHERE` 中使用图 pattern)。 |
|语句文本换行 | 换行符 | `\` + 换行符 |
|Label 与 Tag 是不同的概念| Label 用于寻找点(点的索引)。 | Tag 用于定义点的一种类型及相应的属性,无索引功能。 |
| 预编译与参数化查询 | 支持 | 仅支持参数化查询。 |
Expand Down
4 changes: 0 additions & 4 deletions docs-2.0/3.ngql-guide/1.nGQL-overview/3.graph-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@
(a:User:Admin)-[]->(b)
```

!!! compatibility "openCypher 兼容性"

nGQL 中的`MATCH`语句不支持用`(a:User:Admin)`匹配多个标签。如需匹配多标签可使用过滤条件,如`WHERE "User" IN tags(n) AND "Admin" IN tags(n)`。

## 属性模式

点和边是图的基本结构。nGQL 在这两种结构上都可以增加属性,方便实现更丰富的模型。
Expand Down
4 changes: 1 addition & 3 deletions docs-2.0/3.ngql-guide/5.operators/1.comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ Nebula Graph 支持的比较符如下。

## OpenCypher 兼容性

- `NULL`的比较操作和 openCypher 不同,行为也可能会改变。在 openCypher 中,`IS [NOT] NULL`通常与`OPTIONAL MATCH`一起使用,但是 nGQL 不支持`OPTIONAL MATCH`。

- openCypher 中没有`EMPTY`,因此不支持在 MATCH 语句中使用`EMPTY`。
openCypher 中没有`EMPTY`,因此不支持在 MATCH 语句中使用`EMPTY`。

## 示例

Expand Down
122 changes: 101 additions & 21 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 @@ -2,7 +2,7 @@

`MATCH`语句提供基于模式(pattern)匹配的搜索功能。

一个`MATCH`语句定义了一个[搜索模式](../1.nGQL-overview/3.graph-patterns.md),用该模式匹配存储在 Nebula Graph 中的数据,然后用`RETURN`子句检索数据。
一个`MATCH`语句定义了一个搜索模式,用该模式匹配存储在 Nebula Graph 中的数据,然后用`RETURN`子句检索数据。

本文示例使用测试数据集 [basketballplayer](../1.nGQL-overview/1.overview.md#basketballplayer) 进行演示。

Expand All @@ -11,9 +11,21 @@
与`GO`或`LOOKUP`等其他查询语句相比,`MATCH`的语法更灵活。`MATCH`语法可以概括如下:

```ngql
MATCH <pattern> [<WHERE clause>] RETURN <output>;
MATCH <pattern> [<clause_1>] RETURN <output> [<clause_2>];
```

- `pattern`:pattern 的详细说明请参见[模式](../1.nGQL-overview/3.graph-patterns.md)。`MATCH`语句支持匹配一个或多个模式,多个模式之间用英文逗号(,)分隔。例如`(a)-[]->(b),(c)-[]->(d)`。

- `clause_1`:支持`WHERE`、`WITH`、`UNWIND`、`OPTIONAL MATCH`子句,也可以使用`MATCH`作为子句。

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

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

从3.0版本开始,`pattern`支持同时匹配多个 Tag、Edge Type,所以返回属性时,需要额外指定 Tag/Edge type 名称。即从`RETURN 变量名.属性名`改为`RETURN 变量名.Tag.属性名`或`RETURN 变量名.Edge_type.属性名`。
cooper-lzy marked this conversation as resolved.
Show resolved Hide resolved

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

## MATCH 工作流程

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

需要匹配拥有多个 Tag 的点,可以用英文冒号(:)。

```ngql
nebula> CREATE TAG actor (name string, age int);
nebula> INSERT VERTEX actor(name, age) VALUES "player100":("Tim Duncan", 42);
nebula> MATCH (v:player:actor) \
RETURN v \
LIMIT 10;
+----------------------------------------------------------------------------------------+
| v |
+----------------------------------------------------------------------------------------+
| ("player100" :actor{age: 42, name: "Tim Duncan"} :player{age: 42, name: "Tim Duncan"}) |
+----------------------------------------------------------------------------------------+
```

### 匹配点的属性

!!! Note
Expand All @@ -131,7 +158,7 @@ nebula> MATCH (v:player{name:"Tim Duncan"}) \

```ngql
nebula> MATCH (v:player) \
WHERE v.name == "Tim Duncan" \
WHERE v.player.name == "Tim Duncan" \
RETURN v;
+----------------------------------------------------+
| v |
Expand Down Expand Up @@ -169,6 +196,7 @@ nebula> MATCH (v:player { name: 'Tim Duncan' })--(v2) \
| v2 |
+-----------------------------------------------------------+
| ("player101" :player{age: 36, name: "Tony Parker"}) |
| ("player101" :player{age: 36, name: "Tony Parker"}) |
| ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) |
+-----------------------------------------------------------+
```
Expand All @@ -182,38 +210,56 @@ nebula> MATCH (v:player { name: 'Tim Duncan' })--(v2) \
在 nGQL 1.x 中,`--`符号用于行内注释,在 nGQL 2.x 中,`--`符号表示出边或入边,不再用于注释。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"})--(v2) \
RETURN v2.name AS Name;
nebula> MATCH (v:player{name:"Tim Duncan"})--(v2:player) \
RETURN v2.player.name AS Name;
+---------------------+
| Name |
+---------------------+
| "Spurs" |
| "Tony Parker" |
| "LaMarcus Aldridge" |
| "Marco Belinelli" |
| "Manu Ginobili" |
| "Manu Ginobili" |
| "Dejounte Murray" |
...
```

用户可以在`--`符号上增加`<`或`>`符号指定边的方向。

```ngql
# -->表示边从 v 开始,指向 v2。对于点 v 来说是出边,对于点 v2 来说是入边。
nebula> MATCH (v:player{name:"Tim Duncan"})-->(v2) \
RETURN v2.name AS Name;
nebula> MATCH (v:player{name:"Tim Duncan"})-->(v2:player) \
RETURN v2.player.name AS Name;
+-----------------+
| Name |
+-----------------+
| "Spurs" |
| "Tony Parker" |
| "Manu Ginobili" |
+-----------------+
```

如果需要判断目标点,可以使用`CASE`表达式。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"})--(v2) \
RETURN \
CASE WHEN v2.team.name IS NOT NULL \
THEN v2.team.name \
WHEN v2.player.name IS NOT NULL \
THEN v2.player.name END AS Name;

+---------------------+
| Name |
+---------------------+
| "Manu Ginobili" |
| "Manu Ginobili" |
| "Spurs" |
| "Dejounte Murray" |
...
```

如果需要扩展模式,可以增加更多点和边。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"})-->(v2)<--(v3) \
RETURN v3.name AS Name;
RETURN v3.player.name AS Name;
+---------------------+
| Name |
+---------------------+
Expand All @@ -227,7 +273,7 @@ nebula> MATCH (v:player{name:"Tim Duncan"})-->(v2)<--(v3) \

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"})-->()<--(v3) \
RETURN v3.name AS Name;
RETURN v3.player.name AS Name;
+---------------------+
| Name |
+---------------------+
Expand Down Expand Up @@ -441,6 +487,20 @@ nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow|serve*2]->(v2) \
+-----------------------------------------------------------+
```

### 匹配多个模式

用户可以用英文逗号(,)分隔多个模式。

```
nebula> MATCH (v1:player{name:"Tim Duncan"}), (v2:team{name:"Spurs"}) \
RETURN v1,v2;
+----------------------------------------------------+----------------------------------+
| v1 | v2 |
+----------------------------------------------------+----------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"}) | ("team204" :team{name: "Spurs"}) |
+----------------------------------------------------+----------------------------------+
```

## 常用检索操作

### 检索点或边的信息
Expand Down Expand Up @@ -513,19 +573,19 @@ nebula> MATCH (v:player{name:"Tim Duncan"}) \

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

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

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) \
RETURN v.age AS Age;
RETURN v.player.age AS Age;
+-----+
| Age |
+-----+
Expand Down Expand Up @@ -636,6 +696,26 @@ nebula> MATCH p=(v:player{name:"Tim Duncan"})-[*..2]->(v2) \
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------+
```

### 多MATCH检索

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

```ngql
nebula> MATCH (m)-[]->(n) WHERE id(m)=="player100" \
MATCH (n)-[]->(l) WHERE id(n)=="player125" \
RETURN id(m),id(n),id(l);
+-------------+-------------+-------------+
| id(m) | id(n) | id(l) |
+-------------+-------------+-------------+
| "player100" | "player125" | "team204" |
| "player100" | "player125" | "player100" |
+-------------+-------------+-------------+
```

### OPTIONAL MATCH检索

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

!!! Performance

Nebula Graph 中`MATCH`语句的性能和资源占用得到了优化,但对性能要求较高时,仍建议使用 `GO`, `LOOKUP`, `|` 和 `FETCH` 等来替代`MATCH`。
39 changes: 39 additions & 0 deletions docs-2.0/3.ngql-guide/7.general-query-statements/optional-match.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# OPTIONAL MATCH

`OPTIONAL MATCH`通常用于`MATCH`语句中,作为`MATCH`语句的可选项去匹配图数据库中的模式,如果图数据库中没有对应的模式,对应的列返回`NULL`。

## openCypher 兼容性

本文操作仅适用于 nGQL 中的 openCypher 方式。

## 示例

`MATCH`语句中使用`OPTIONAL MATCH`的示例如下:

```ngql
nebula> MATCH (m)-[]->(n) WHERE id(m)=="player100" \
OPTIONAL MATCH (n)-[]->(l) WHERE id(n)=="player125" \
RETURN id(m),id(n),id(l);
+-------------+-------------+-------------+
| id(m) | id(n) | id(l) |
+-------------+-------------+-------------+
| "player100" | "team204" | __NULL__ |
| "player100" | "player101" | __NULL__ |
| "player100" | "player125" | "team204" |
| "player100" | "player125" | "player100" |
+-------------+-------------+-------------+
```

而使用多`MATCH`,不使用`OPTIONAL MATCH`时,会返回模式完全匹配的行。示例如下:

```ngql
nebula> MATCH (m)-[]->(n) WHERE id(m)=="player100" \
MATCH (n)-[]->(l) WHERE id(n)=="player125" \
RETURN id(m),id(n),id(l);
+-------------+-------------+-------------+
| id(m) | id(n) | id(l) |
+-------------+-------------+-------------+
| "player100" | "player125" | "team204" |
| "player100" | "player125" | "player100" |
+-------------+-------------+-------------+
```
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ nebula> MATCH p=(v:player{name:"Tim Duncan"})--(v2) \
+----------------------------------------------------------------------------------------------------------------------+
| collect(r) |
+----------------------------------------------------------------------------------------------------------------------+
| [("player100" :player{age: 42, name: "Tim Duncan"}), ("player101" :player{age: 36, name: "Tony Parker"}),
("team204" :team{name: "Spurs"}), ("player102" :player{age: 33, name: "LaMarcus Aldridge"}),
("player125" :player{age: 41, name: "Manu Ginobili"}), ("player104" :player{age: 32, name: "Marco Belinelli"}),
("player144" :player{age: 47, name: "Shaquile O'Neal"}), ("player105" :player{age: 31, name: "Danny Green"}),
("player113" :player{age: 29, name: "Dejounte Murray"}), ("player107" :player{age: 32, name: "Aron Baynes"}),
("player109" :player{age: 34, name: "Tiago Splitter"}), ("player108" :player{age: 36, name: "Boris Diaw"})] |
| [("player100" :player{age: 42, name: "Tim Duncan"}), ("player101" :player{age: 36, name: "Tony Parker"}), |
|("team204" :team{name: "Spurs"}), ("player102" :player{age: 33, name: "LaMarcus Aldridge"}), |
|("player125" :player{age: 41, name: "Manu Ginobili"}), ("player104" :player{age: 32, name: "Marco Belinelli"}), |
|("player144" :player{age: 47, name: "Shaquile O'Neal"}), ("player105" :player{age: 31, name: "Danny Green"}), |
|("player113" :player{age: 29, name: "Dejounte Murray"}), ("player107" :player{age: 32, name: "Aron Baynes"}), |
|("player109" :player{age: 34, name: "Tiago Splitter"}), ("player108" :player{age: 36, name: "Boris Diaw"})] |
+----------------------------------------------------------------------------------------------------------------------+
```
3 changes: 2 additions & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,10 @@ nav:

- 通用查询语句:
- MATCH: 3.ngql-guide/7.general-query-statements/2.match.md
- OPTIONAL MATCH: 3.ngql-guide/7.general-query-statements/optional-match.md
- LOOKUP: 3.ngql-guide/7.general-query-statements/5.lookup.md
- GO: 3.ngql-guide/7.general-query-statements/3.go.md
- FETCH: 3.ngql-guide/7.general-query-statements/4.fetch.md
- UNWIND: 3.ngql-guide/7.general-query-statements/7.unwind.md
- SHOW:
- SHOW CHARSET: 3.ngql-guide/7.general-query-statements/6.show/1.show-charset.md
- SHOW COLLATION: 3.ngql-guide/7.general-query-statements/6.show/2.show-collation.md
Expand Down Expand Up @@ -227,6 +227,7 @@ nav:
- WHERE: 3.ngql-guide/8.clauses-and-options/where.md
- YIELD: 3.ngql-guide/8.clauses-and-options/yield.md
- WITH: 3.ngql-guide/8.clauses-and-options/with.md
- UNWIND: 3.ngql-guide/8.clauses-and-options/unwind.md

- 图空间语句:
- CREATE SPACE: 3.ngql-guide/9.space-statements/1.create-space.md
Expand Down