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 limit syntax #1082

Merged
merged 6 commits into from
Oct 22, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
101 changes: 78 additions & 23 deletions docs-2.0/3.ngql-guide/8.clauses-and-options/limit.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,55 @@
# LIMIT

`LIMIT`子句限制输出结果的行数。
`LIMIT`子句限制输出结果的行数。`LIMIT`在原生nGQL语句和openCypher兼容语句中的用法有所不同。

- 在原生nGQL中,必须使用管道符(|),可以忽略偏移量
- 在原生nGQL语句中,一般需要在`LIMIT`子句前使用管道符,可以直接在LIMIT语句后设置或者省略偏移量参数

- 在openCypher方式中,不允许使用管道符,可以使用`SKIP`指明偏移量。
- 在openCypher兼容语句中,不允许在`LIMIT`子句前使用管道符,可以使用`SKIP`指明偏移量。

!!! Note

在原生nGQL或openCypher方式中使用`LIMIT`时,使用`ORDER BY`子句限制输出顺序非常重要,否则会输出一个不可预知的子集。

## 原生nGQL语法
!!! compatibility "历史版本兼容性"

在原生nGQL中,`LIMIT`的工作原理与`SQL`相同,必须和管道符一起使用。`LIMIT`子句接收一个或两个参数。参数的值必须是非负整数。
Nebula Graph 2.6.0中,`GO`语句支持了新的`LIMIT`语法。部分`LIMIT`相关的算子支持计算下推。

## 原生nGQL语句中的LIMIT

在原生nGQL中,`LIMIT`有通用语法和`GO`语句中的专属语法。

### 原生nGQL中的通用LIMIT语法

原生nGQL中的通用`LIMIT`语法与`SQL`中的`LIMIT`原理相同。`LIMIT`子句接收一个或两个参数,参数的值必须是非负整数,且必须用在管道符之后。语法和说明如下:

```ngql
YIELD <var>
[| LIMIT [<offset_value>,] <number_rows>];
... | LIMIT [<offset>,] <number_rows>;
```

|参数|说明|
|:--|:--|
|`var`|排序的列或计算结果。|
|`offset_value`|偏移量,即定义从哪一行开始返回。索引从`0`开始。默认值为`0`,表示从第一行开始返回。|
|`offset`|偏移量,即定义从哪一行开始返回。索引从`0`开始。默认值为`0`,表示从第一行开始返回。|
|`number_rows`|返回的总行数。|

### 示例
示例:

```ngql
# 从排序结果中返回第2行开始的3行数据。
# 从结果中返回最前面的3行数据。
nebula> LOOKUP ON player |\
LIMIT 3;
+-------------+
| VertexID |
+-------------+
| "player100" |
| "player101" |
| "player102" |
+-------------+

# 从排序后结果中返回第2行开始的3行数据。
nebula> GO FROM "player100" OVER follow REVERSELY \
YIELD properties($$).name AS Friend, properties($$).age AS Age \
| ORDER BY $-.Age, $-.Friend \
| LIMIT 1, 3;
YIELD properties($$).name AS Friend, properties($$).age AS Age \|
ORDER BY $-.Age, $-.Friend \|
LIMIT 1, 3;
+-------------------+-----+
| Friend | Age |
+-------------------+-----+
Expand All @@ -44,17 +61,50 @@ nebula> GO FROM "player100" OVER follow REVERSELY \
+-------------------+-----+
```

## openCypher方式语法
### GO语句中的LIMIT

`GO`语句中的`LIMIT`除了支持原生nGQL中的通用语法外,还支持根据边限制输出结果数量。

语法:

```ngql
<go_statement> LIMIT <limit_list>;
```

`limit_list`是一个列表,列表中的元素必须为自然数,且元素数量必须与`GO`语句中的`STEPS`的最大数相同。下文以`GO 1 TO 3 STEPS FROM "A" OVER * LIMIT <limit_list>`为例详细介绍`LIMIT`的这种用法。

* 列表`limit_list`必须包含3个自然数元素,例如`GO 1 TO 3 STEPS FROM "A" OVER * LIMIT [1,2,4]`。
* `LIMIT [1,2,4]`中的`1`表示系统在第一步时自动选择1条边继续遍历,`2`表示在第二步时选择2条边继续遍历,`4`表示在第三步时选择4条边继续遍历。
* 因为`GO 1 TO 3 STEPS`表示返回第一到第三步的所有遍历结果,因此下图中所有红色边和它们的原点与目的点都会被这条`GO`语句匹配上,而黄色边表示`GO`语句遍历时没有选择的路径。如果不是`GO 1 TO 3 STEPS`而是`GO 3 STEPS`,则只会匹配上第三步的红色边和它们两端的点。

![LIMIT in GO](limit_in_go_1.png)

在basketballplayer数据集中的执行示例如下:

```ngql
RETURN <var>
[SKIP <offset>]
[LIMIT <number_rows>];
nebula> GO 3 STEPS FROM "player100" \
OVER * \
YIELD properties($$).name AS NAME, properties($$).age AS Age \
LIMIT [3,3,3];
+-----------------+--------------+
| NAME | Age |
+-----------------+--------------+
| "Spurs" | UNKNOWN_PROP |
| "Tony Parker" | 36 |
| "Manu Ginobili" | 41 |
+-----------------+--------------+
```

## openCypher兼容语句中的LIMIT

在`MATCH`等openCypher兼容语句中使用LIMIT不需要加管道符。语法和说明如下:

```ngql
... [SKIP <offset>] [LIMIT <number_rows>];
```

|参数|说明|
|:--|:--|
|`var`|排序的列或计算结果。|
|`offset`|偏移量,即定义从哪一行开始返回。索引从`0`开始。默认值为`0`,表示从第一行开始返回。|
|`number_rows`|返回的总行数量。|

Expand All @@ -64,7 +114,9 @@ RETURN <var>

两个整数组成的分数表达式会自动向下取整。例如`8/6`向下取整为1。

### 示例
### 单独使用LIMIT

`LIMIT`可以单独使用,返回指定数量的结果。

```ngql
nebula> MATCH (v:player) RETURN v.name AS Name, v.age AS Age \
Expand Down Expand Up @@ -98,9 +150,9 @@ nebula> MATCH (v:player) RETURN v.name AS Name, v.age AS Age \
+-------------------------+-----+
```

### SKIP示例
### 单独使用SKIP

用户可以单独使用`SKIP <offset>`设置偏移量,后面不需要添加`LIMIT <number_rows>`
`SKIP`可以单独使用,用于设置偏移量,返回指定位置之后的数据

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) --> (v2) \
Expand All @@ -124,7 +176,9 @@ nebula> MATCH (v:player{name:"Tim Duncan"}) --> (v2) \
+---------------+-----+
```

用户也可以同时使用`SKIP <offset>`和`LIMIT <number_rows>`,返回中间的部分数据。
### 同时使用SKIP与LIMIT

同时使用`SKIP`与`LIMIT`可以返回从指定位置开始的指定数量的数据。

```ngql
nebula> MATCH (v:player{name:"Tim Duncan"}) --> (v2) \
Expand All @@ -136,6 +190,7 @@ nebula> MATCH (v:player{name:"Tim Duncan"}) --> (v2) \
| "Manu Ginobili" | 41 |
+-----------------+-----+
```

<!--
## 性能提示

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.