跳转至
开发版采用单机部署,无需产品 License 文件。需要多机部署或大规模性能测试? 了解企业版

SAMPLE

SAMPLE子句用于在遍历过程中对边采样。在处理超大数据集时,可通过该子句选取较小且易于处理的样本进行分析。

取决于遍历的方向,SAMPLE子句可分为两种类型:向右采样(SAMPLE RIGHT)和向左采样(SAMPLE LEFT)。目前仅支持向右采样(SAMPLE RIGHT)。

在悦数图数据库开发版持久图中,SAMPLE子句直接用于MATCH语句中的边模式。

使用说明

  • 不支持在临时图中使用SAMPLE子句。
  • SAMPLE子句只能写在边模式上,不能写在点模式上。
  • SAMPLE子句不能用于涉及边匹配的近似最邻近查询。更多信息,请参见最近邻查询。
  • 若推断得到无向的边类型,则不支持采样。无向边类型的方向声明如下:~[ edge_pattern_filler ]~。更多信息,请参见 CREATE GRAPH TYPE。

工作原理

SAMPLE子句必须指定为完整边模式的边模式填充器的组件;且如果边模式填充器中同时指定了 WHERE 子句,则SAMPLE子句必须写在WHERE子句之前。采样会在WHERE子句中的过滤条件应用之前执行。关于边模式填充器中各组件出现顺序的更多信息,请参见完整边模式。

采样对象为包含SAMPLE子句的完整边模式所匹配到的边。

所谓向右采样,也即对锚定点右侧的边进行采样,锚定点即为遍历的起始点。例如,在边模式(v1)<-[e SAMPLE RIGHT]->{1,2}(v2)中,v1即为锚定点。

采样行为由采样上下文决定,后者由以下四个部分组成:

  • 锚定点
  • 连接锚定点的边的边类型
  • 连接锚定点的边的方向
  • 边模式的每一跳

在遍历过程中,不同的采样上下文相互独立。针对每个采样上下文,会根据指定的采样方法和采样大小对边进行采样。

语法

sample_clause
SAMPLE RIGHT sampling_method sample_size
sampling_method
FIRST_FETCH RANDOM UNIQUE_NEIGHBOR UNQ_NBR
sample_size
unsigned_integer %

sample_clause ::=
    'SAMPLE' 'RIGHT'? sampling_method? sample_size

sampling_method ::=
    'FIRST_FETCH' | 'RANDOM' | 'UNIQUE_NEIGHBOR' | 'UNQ_NBR'

sample_size ::=
    unsigned_integer '%'?                

参数

指定采样时遍历方向的可选关键字。当前仅支持向右采样。

若未指定该关键字,默认为向右采样。

sampling_method

对于每个采样上下文,选用的采样方法。有效值包括:

  • FIRST_FETCH:采样前 N 条边。此为默认值。
  • RANDOM:随机采样边。
  • UNIQUE_NEIGHBOR或UNQ_NBR:随机采样连接唯一邻点的边。连接同一对点的平行边会去重后再进行采样。

sample_size

对于每个采样上下文,采样的大小。支持以下两种指定格式:

  • 一个无符号整数,代表最大采样数。此时,该无符号整数必须为正整数。
  • 一个后跟百分号(%)的无符号整数,代表采样百分比。此时,该无符号整数必须在[0, 100]范围内。若计算结果为小数,则向上取整。

示例

采样前 2 条边

'''
USE movie
MATCH (v1{id: 18})<-[e SAMPLE RIGHT FIRST_FETCH 2 ]-(v2) 
RETURN labels(v1) AS anchor_labels,
       v1.id AS anchor_business_id,
       type(e) AS edge_type,
       count(*) AS sampled_count
'''

返回:

+---------------+--------------------+-----------+---------------+
| anchor_labels | anchor_business_id | edge_type | sampled_count |
+---------------+--------------------+-----------+---------------+
| [Genre]       | 18                 | WithGenre | 2             |
| [Movie]       | 18                 | Direct    | 1             |
| [Movie]       | 18                 | Act       | 2             |
+---------------+--------------------+-----------+---------------+

上述返回显示存在 3 个采样上下文,具体如下:

  1. 对于标签为Movie且业务属性id为18的锚定点,采样了两条边类型为Act的边。
  2. 对于标签为Movie且业务属性id为18的锚定点,采样了一条边类型为Direct的边。原因是数据集中仅存在一条此类边。
  3. 对于标签为Genre且业务属性id为18的锚定点,采样了两条边类型为WithGenre的边。

随机采样 10% 的边

'''
USE movie
MATCH (v1{id: 18})<-[e SAMPLE RIGHT RANDOM 10% ]->(v2)
RETURN labels(v1) AS anchor_labels,
       v1.id AS anchor_business_id,
       type(e) AS edge_type,
       count(*) AS sampled_count
'''

返回:

+---------------+--------------------+-----------+---------------+
| anchor_labels | anchor_business_id | edge_type | sampled_count |
+---------------+--------------------+-----------+---------------+
| [Movie]       | 18                 | WithGenre | 2             |
| [Genre]       | 18                 | WithGenre | 3             |
| [Person]      | 18                 | Watch     | 3             |
| [Movie]       | 18                 | Direct    | 1             |
| [Movie]       | 18                 | Act       | 5             |
+---------------+--------------------+-----------+---------------+

上述返回显示存在 5 个采样上下文,具体如下:

  1. 对于标签为Movie且业务属性id为18的锚定点,采样了五条边类型为Act的边。实际存在 44 条此类边,44 的 10% 向上取整即为 5。
  2. 对于标签为Movie且业务属性id为18的锚定点,采样了一条边类型为Direct的边。
  3. 对于标签为Movie且业务属性id为18的锚定点,采样了两条边类型为WithGenre的边。
  4. 对于标签为Person且业务属性id为18的锚定点,采样了三条边类型为Watch的边。
  5. 对于标签为Genre且业务属性id为18的锚定点,采样了三条边类型为WithGenre的边。

随机采样 2 条连接唯一邻点的边

'''
USE movie 
MATCH p = (v1@Genre{id: 18})<-[e SAMPLE RIGHT UNIQUE_NEIGHBOR 2]-{1,2}(v2)
RETURN length(p) AS hops,
       transform(nodes(p), n -> n.id) AS node_business_ids,
       transform(e, edge -> type(edge)) AS edge_types
'''

返回示例:

+------+-------------------+--------------------+
| hops | node_business_ids | edge_types         |
+------+-------------------+--------------------+
| 1    | [18,346]          | [WithGenre]        |
| 1    | [18,601]          | [WithGenre]        |
| 2    | [18,346,20831]    | [WithGenre,Act]    |
| 2    | [18,601,330]      | [WithGenre,Watch]  |
| 2    | [18,346,5026]     | [WithGenre,Direct] |
| 2    | [18,601,23764]    | [WithGenre,Act]    |
| 2    | [18,346,339]      | [WithGenre,Watch]  |
| 2    | [18,346,7457]     | [WithGenre,Act]    |
| 2    | [18,346,603]      | [WithGenre,Watch]  |
| 2    | [18,601,488]      | [WithGenre,Direct] |
| 2    | [18,601,9981]     | [WithGenre,Act]    |
| 2    | [18,601,580]      | [WithGenre,Watch]  |
+------+-------------------+--------------------+

上述返回显示存在 7 个采样上下文,具体如下:

  1. 从业务属性id为18的Genre锚定点出发,第一跳采样了两条WithGenre边,分别连接业务属性id为346和601的两个Movie点。
  2. 从业务属性id为346的Movie点继续遍历第二跳:
    1. 采样了两条边类型为Act的边,分别连接了两个唯一邻点。
    2. 采样了一条边类型为Direct的边。
    3. 采样了两条边类型为Watch的边,分别连接了两个唯一邻点。
  3. 从业务属性id为601的Movie点继续遍历第二跳:
    1. 采样了两条边类型为Act的边,分别连接了两个唯一邻点。
    2. 采样了一条边类型为Direct的边。
    3. 采样了两条边类型为Watch的边,分别连接了两个唯一邻点。

采样大小2会分别应用于每个采样上下文,而不是限制整个查询只返回两条边。由于示例数据集中不存在平行边,因此采样结果中的边均连接唯一邻点。随机采样的具体结果可能因每次执行而不同。