Link Search Menu Expand Document Documentation Menu

命令

PPL 支持大多数 SQL 常用函数,包括 相关性搜索,但也引入了更多只在 PPL 中可用的函数(称为 命令)。

dedup

`dedup`(数据去重)命令根据字段从搜索结果中删除重复文档。

语法

dedup [int] <field-list> [keepempty=<bool>] [consecutive=<bool>]
字段 描述 类型 必需 默认值
整数 为每个组合保留指定数量的重复事件。该数字必须大于 0。如果您未指定数字,则只保留第一次出现的事件,所有其他重复项将从结果中删除。 字符串 1
keepempty 如果为 true,则当字段列表中的任何字段具有 null 值或缺少字段时,保留该文档。 嵌套对象列表 False
consecutive 如果为 true,则仅删除具有重复值组合的连续事件。 布尔型 False
字段列表 指定一个逗号分隔的字段列表。至少需要一个字段。 String 或逗号分隔的字符串列表 -

示例 1:按单个字段去重

删除性别相同的重复文档

search source=accounts | dedup gender | fields account_number, gender;
account_number gender
1 M
13 F

示例 2:保留两个重复文档

保留两个性别相同的重复文档

search source=accounts | dedup 2 gender | fields account_number, gender;
account_number gender
1 M
6 M
13 F

示例 3:默认保留或忽略空字段

保留两个字段值为 null 的重复文档

search source=accounts | dedup email keepempty=true | fields account_number, email;
account_number email
1 amberduke@pyrami.com
6 hattiebond@netagy.com
13 null
18 daleadams@boink.com

删除字段值为 null 的重复文档

search source=accounts | dedup email | fields account_number, email;
account_number email
1 amberduke@pyrami.com
6 hattiebond@netagy.com
18 daleadams@boink.com

示例 4:连续文档去重

删除连续重复文档

search source=accounts | dedup gender consecutive=true | fields account_number, gender;
account_number gender
1 M
13 F
18 M

限制

`dedup` 命令不会被重写为 OpenSearch DSL,它只在协调节点上执行。

eval

`eval` 命令评估表达式并将其结果附加到搜索结果中。

语法

eval <field>=<expression> ["," <field>=<expression> ]...
字段 描述 必需
字段 如果字段名不存在,则添加新字段。如果字段名已存在,则会被覆盖。
表达式 指定任何支持的表达式。

示例 1:创建新字段

为每个文档创建新的 `doubleAge` 字段。`doubleAge` 是 `age` 乘以 2 的结果

search source=accounts | eval doubleAge = age * 2 | fields age, doubleAge;
age doubleAge
32 64
36 72
28 56
33 66

示例 2:覆盖现有字段

用 `age` 加 1 覆盖 `age` 字段

search source=accounts | eval age = age + 1 | fields age;
age
33
37
29
34

示例 3:使用 `eval` 命令定义的字段创建新字段

创建新字段 `ddAge`。`ddAge` 是 `doubleAge` 乘以 2 的结果,其中 `doubleAge` 是在 `eval` 命令中定义的

search source=accounts | eval doubleAge = age * 2, ddAge = doubleAge * 2 | fields age, doubleAge, ddAge;
age doubleAge ddAge
32 64 128
36 72 144
28 56 112
33 66 132

限制

`eval` 命令不会被重写为 OpenSearch DSL,它只在协调节点上执行。

fields

使用 `fields` 命令从搜索结果中保留或删除字段。

语法

fields [+|-] <field-list>
字段 描述 必需 默认值
修饰符 加号 (+) 只保留字段列表中指定的字段。减号 (-) 删除字段列表中指定的所有字段。 +
字段列表 指定一个逗号分隔的字段列表。 无默认值

示例 1:从结果中选择指定字段

从搜索结果中获取 `account_number`、`firstname` 和 `lastname` 字段

search source=accounts | fields account_number, firstname, lastname;
account_number firstname lastname
1 Amber Duke
6 Hattie Bond
13 Nanette Bates
18 Dale Adams

示例 2:从搜索结果中删除指定字段

从搜索结果中删除 `account_number` 字段

search source=accounts | fields account_number, firstname, lastname | fields - account_number;
firstname lastname
Amber Duke
Hattie Bond
Nanette Bates
Dale Adams

parse

使用 `parse` 命令通过正则表达式解析文本字段,并将结果附加到搜索结果中。

语法

parse <field> <regular-expression>
字段 描述 必需
字段 一个文本字段。
正则表达式 用于从给定文本字段中提取新字段的正则表达式。如果新字段名已存在,它将替换原始字段。

正则表达式用于使用 Java 正则表达式引擎匹配每个文档的整个文本字段。表达式中每个命名捕获组都将成为一个新的 STRING 字段。

示例 1:创建新字段

此示例展示了如何为每个文档创建新字段 `host`。`host` 将是 `email` 字段中 `@` 符号后的主机名。解析 null 字段将返回一个空字符串。

os> source=accounts | parse email '.+@(?<host>.+)' | fields email, host ;
fetched rows / total rows = 4/4
email host
amberduke@pyrami.com pyrami.com
hattiebond@netagy.com netagy.com
null null
daleadams@boink.com boink.com

示例 2:覆盖现有字段

此示例展示了如何覆盖现有地址字段,并移除街道号码。

os> source=accounts | parse address '\d+ (?<address>.+)' | fields address ;
fetched rows / total rows = 4/4
address
Holmes Lane
Bristol Street
Madison Street
Hutchinson Court

示例 3:过滤并排序已转换的解析字段

此示例展示了如何对地址字段中大于 500 的街道号码进行排序。

os> source=accounts | parse address '(?<streetNumber>\d+) (?<street>.+)' | where cast(streetNumber as int) > 500 | sort num(streetNumber) | fields streetNumber, street ;
fetched rows / total rows = 3/3
streetNumber street
671 Bristol Street
789 Madison Street
880 Holmes Lane

限制

使用 parse 命令时存在一些限制

  • 由 parse 定义的字段不能再次解析。例如,source=accounts | parse address '\\d+ (?<street>.+)' | parse street '\\w+ (?<road>\\w+)' ; 将无法返回任何表达式。
  • 由 parse 定义的字段不能被其他命令覆盖。例如,当输入 source=accounts | parse address '\\d+ (?<street>.+)' | eval street='1' | where street='1' ; 时,where 将不会匹配任何文档,因为 street 不能被覆盖。
  • `parse` 命令使用的文本字段不能被覆盖。例如,当输入 source=accounts | parse address '\\d+ (?<street>.+)' | eval address='1' ; 时,street 将不会被解析,因为 `address` 被覆盖了。
  • 由 parse 定义的字段在 stats 命令中使用后不能进行过滤/排序。例如,source=accounts | parse email '.+@(?<host>.+)' | stats avg(age) by host | where host=pyrami.com ; 中的 where 将不会解析列出的域名。

rename

使用 `rename` 命令重命名搜索结果中的一个或多个字段。

语法

rename <source-field> AS <target-field>["," <source-field> AS <target-field>]...
字段 描述 必需
源字段 您要重命名的字段名称。
目标字段 您要重命名为的名称。

示例 1:重命名单个字段

将 `account_number` 字段重命名为 `an`

search source=accounts | rename account_number as an | fields an;
an
1
6
13
18

示例 2:重命名多个字段

将 `account_number` 字段重命名为 `an`,并将 `employer` 重命名为 `emp`

search source=accounts | rename account_number as an, employer as emp | fields an, emp;
an emp
1 Pyrami
6 Netagy
13 Quility
18 null

限制

`rename` 命令不会被重写为 OpenSearch DSL,它只在协调节点上执行。

sort(排序)

使用 `sort` 命令按指定字段对搜索结果进行排序。

语法

sort [count] <[+|-] sort-field>...
字段 描述 必需 默认值
计数 从排序结果中返回的最大结果数量。如果 count=0,则返回所有结果。 1000
[+|-] 使用加号 [+] 按升序排序,使用减号 [-] 按降序排序。 升序
排序字段 指定您要排序的字段。 -

示例 1:按单个字段排序

按 `age` 字段升序排序所有文档

search source=accounts | sort age | fields account_number, age;
account_number age
13 28
1 32
18 33
6 36

示例 2:按单个字段排序并返回所有结果

按 `age` 字段升序排序所有文档,并将 count 指定为 0 以获取所有结果

search source=accounts | sort 0 age | fields account_number, age;
account_number age
13 28
1 32
18 33
6 36

示例 3:按单个字段降序排序

按 `age` 字段降序排序所有文档

search source=accounts | sort - age | fields account_number, age;
account_number age
6 36
18 33
1 32
13 28

示例 4:指定要返回的排序文档数量

按 `age` 字段升序排序所有文档,并将 count 指定为 2 以获取两个结果

search source=accounts | sort 2 age | fields account_number, age;
account_number age
13 28
1 32

示例 5:按多个字段排序

按 `gender` 字段升序和 `age` 字段降序排序所有文档

search source=accounts | sort + gender, - age | fields account_number, gender, age;
account_number gender age
13 F 28
6 M 36
18 M 33
1 M 32

stats

使用 `stats` 命令从搜索结果中进行聚合。

下表列出了聚合函数,并指明了每个函数如何处理 null 或缺失值

功能 NULL 缺失
计数 不计数 不计数
求和 忽略 忽略
平均值 忽略 忽略
最大值 忽略 忽略
最小值 忽略 忽略

语法

stats <aggregation>... [by-clause]...
字段 描述 必需 默认值
聚合 指定一个统计聚合函数。该函数的参数必须是一个字段。 1000
by 子句 指定一个或多个字段来对结果进行分组。如果未指定,`stats` 命令将只返回一行,即对整个结果集进行聚合。 -

示例 1:计算字段的平均值

计算所有文档的平均 `age`

search source=accounts | stats avg(age);
avg(age)
32.25

示例 2:按组计算字段的平均值

按性别分组计算平均年龄

search source=accounts | stats avg(age) by gender;
gender avg(age)
F 28.0
M 33.666666666666664

示例 3:按组计算字段的平均值和总和

按性别分组计算年龄的平均值和总和

search source=accounts | stats avg(age), sum(age) by gender;
gender avg(age) sum(age)
F 28 28
M 33.666666666666664 101

示例 4:计算字段的最大值

计算最大年龄

search source=accounts | stats max(age);
max(age)
36

示例 5:按组计算字段的最大值和最小值

按性别分组计算年龄的最大值和最小值

search source=accounts | stats max(age), min(age) by gender;
gender min(age) max(age)
F 28 28
M 32 36

其中

使用 `where` 命令与布尔表达式一起过滤搜索结果。`where` 命令仅当布尔表达式评估为 true 时才返回结果。

语法

where <boolean-expression>
字段 描述 必需
布尔表达式 评估为布尔值的表达式。

示例:使用条件过滤结果集

获取 `accounts` 索引中 `account_number` 为 1 或性别为 `F` 的所有文档

search source=accounts | where account_number=1 or gender=\"F\" | fields account_number, gender;
account_number gender
1 M
13 F

使用 `head` 命令返回指定搜索顺序中的前 N 个结果。

语法

head [N]
字段 描述 必需 默认值
N 指定要返回的结果数量。 10

示例 1:获取前 10 个结果

获取前 10 个结果

search source=accounts | fields firstname, age | head;
firstname age
Amber 32
Hattie 36
Nanette 28

示例 2:获取前 N 个结果

获取前两个结果

search source=accounts | fields firstname, age | head 2;
firstname age
Amber 32
Hattie 36

限制

`head` 命令不会被重写为 OpenSearch DSL,它只在协调节点上执行。

rare

使用 `rare` 命令查找字段列表中所有字段的最不常见值。对于每个不同的分组字段值集,最多返回 10 个结果。

语法

rare <field-list> [by-clause]
字段 描述 必需
字段列表 指定一个逗号分隔的字段名列表。
by 子句 指定一个或多个字段来对结果进行分组。

示例 1:查找字段中最不常见的值

查找性别中最不常见的值

search source=accounts | rare gender;
gender
F
M

示例 2:按性别分组查找最不常见的值

按性别分组查找最不常见的年龄

search source=accounts | rare age by gender;
gender age
F 28
M 32
M 33

限制

`rare` 命令不会被重写为 OpenSearch DSL,它只在协调节点上执行。

top

使用 `top` 命令查找字段列表中所有字段最常见的值。

语法

top [N] <field-list> [by-clause]
字段 描述 默认值
N 指定要返回的结果数量。 10
字段列表 指定一个逗号分隔的字段名列表。 -
by 子句 指定一个或多个字段来对结果进行分组。 -

示例 1:查找字段中最常见的值

查找最常见的性别

search source=accounts | top gender;
gender
M
F

示例 2:查找字段中最常见的值

查找最常见的性别

search source=accounts | top 1 gender;
gender
M

示例 3:按性别分组查找最常见的值

按性别分组查找最常见的年龄

search source=accounts | top 1 age by gender;
gender age
F 28
M 32

限制

`top` 命令不会被重写为 OpenSearch DSL,它只在协调节点上执行。

`ad` 命令将 ML Commons 插件中的 Random Cut Forest (RCF) 算法应用于 PPL 命令返回的搜索结果。根据输入,该插件使用两种 RCF 算法:用于处理时间序列数据的固定时间 RCF 和用于处理非时间序列数据的批量 RCF。

语法:时间序列数据的固定时间 RCF 命令

ad <shingle_size> <time_decay> <time_field>
字段 描述 必需
瓦片大小 最近记录的连续序列。默认值为 8。
时间衰减 指定计算异常分数时要考虑的最近历史记录的量。默认值为 0.001。
时间字段 指定 RCF 用作时间序列数据的时间字段。必须是长整型值(例如毫秒级时间戳)或“yyyy-MM-dd HH:mm:ss”格式的字符串值。

语法:非时间序列数据的批处理 RCF 命令

ad <shingle_size> <time_decay>
字段 描述 必需
瓦片大小 最近记录的连续序列。默认值为 8。
时间衰减 指定计算异常分数时要考虑的最近历史记录的量。默认值为 0.001。

示例 1:使用时间序列数据从纽约市出租车乘客量数据中检测事件

该示例训练一个 RCF 模型,并使用该模型检测时间序列乘客量数据中的异常。

PPL 查询

os> source=nyc_taxi | fields value, timestamp | AD time_field='timestamp' | where value=10844.0
时间戳 分数 异常等级
10844.0 1404172800000 0.0 0.0

示例 2:使用非时间序列数据从纽约市出租车乘客量数据中检测事件

PPL 查询

os> source=nyc_taxi | fields value | AD | where value=10844.0
分数 异常的  
  10844.0 0.0

kmeans

kmeans 命令将 ML Commons 插件的 kmeans 算法应用于所提供的 PPL 命令的搜索结果。

语法

kmeans <cluster-number>

对于 cluster-number,输入您希望将数据点分组到的集群数量。

示例:鸢尾花数据分组

该示例展示了如何根据从每个样本测量的四个特征(花萼和花瓣的长度和宽度)的组合来对三种鸢尾花物种(香根鸢尾、弗吉尼亚鸢尾和变色鸢尾)进行分类。

PPL 查询

os> source=iris_data | fields sepal_length_in_cm, sepal_width_in_cm, petal_length_in_cm, petal_width_in_cm | kmeans centroids=3
花萼长度(厘米) 花萼宽度(厘米) 花瓣长度(厘米) 花瓣宽度(厘米) 集群 ID  
  5.1 3.5 1.4 0.2 1
  5.6 3.0 4.1 1.3 0
  6.7 2.5 5.8 1.8 2

join

这是一项实验性功能,不建议在生产环境中使用。有关此功能的进展更新或您想留下反馈,请加入 OpenSearch 论坛的讨论。

您可以使用 join 命令合并两个数据集。左侧可以是索引或管道命令的结果,而右侧可以是索引或子查询。

语法

[join-type] join [left-alias] [right-alias] on <join-criteria> <right-dataset>
* joinCriteria: mandatory. It could be any comparison expression.
* right-dataset: mandatory. Right dataset could be either an index or a subquery with/without alias.
字段 描述 类型 必需 默认值
连接类型 要执行的连接类型。有效值为 innerleftrightfullcrosssemianti 字符串 inner
左别名 用于左连接侧的子查询别名,以避免命名歧义。固定模式:left = <left-alias> 字符串 不适用
右别名 用于右连接侧的子查询别名,以避免命名歧义。固定模式:right = <right-alias> 字符串 不适用
连接条件 任何比较表达式。 字符串 不适用
右数据集 带有或不带有别名的索引或子查询。 字符串 不适用

以下示例使用 state_countryoccupation 索引。

state_country:

名称 年龄 状态 国家
Jake 70 加利福尼亚 美国
Hello 30 纽约 美国
John 25 安大略 加拿大
Jane 20 魁北克 加拿大
Jim 27 不列颠哥伦比亚省 加拿大
Peter 57 不列颠哥伦比亚省 加拿大
Rick 70 不列颠哥伦比亚省 加拿大
David 40 华盛顿 美国

occupation:

名称 职业 国家 薪水
Jake 工程师 英格兰 100000
Hello 艺术家 美国 70000
John 医生 加拿大 120000
David 医生 美国 120000
David 失业者 加拿大 0
Jane 科学家 加拿大 90000

示例 1:连接两个索引

以下示例对两个索引执行内连接

search source = state_country
| inner join left=a right=b ON a.name = b.name occupation
| stats avg(salary) by span(age, 10) as age_span, b.country
平均薪水 年龄跨度 b.country
120000.0 40 美国
105000.0 20 加拿大
0.0 40 加拿大
70000.0 30 美国
100000.0 70 英格兰

示例 2:与子搜索连接

以下示例与子搜索执行左连接

search source = state_country as a
| where country = 'USA' OR country = 'England'
| left join on a.name = b.name [
    source = occupation
    | where salary > 0
    | fields name, country, salary
    | sort salary
    | head 3
  ] as b
| stats avg(salary) by span(age, 10) as age_span, b.country
平均薪水 年龄跨度 b.country
null 40 null
70000.0 30 美国
100000.0 70 英格兰

限制

join 命令仅在 plugins.calcite.enabled 设置为 true 时才有效。

lookup

这是一项实验性功能,不建议在生产环境中使用。有关此功能的进展更新或您想留下反馈,请加入 OpenSearch 论坛的讨论。

lookup 命令通过添加或替换来自查找索引(维度表)的数据来丰富您的搜索数据。当查找条件匹配时,您可以使用维度表中的值扩展索引字段或追加/替换值。lookup 命令是 join 命令的替代方案,更适合使用静态数据集丰富源数据。

语法

lookup <lookup-index> (<lookup-mapping-field> [as <source-mapping-field>])... [(replace | append) (<input-field> [AS <output-field>])...]
字段 描述 必需 默认值
查找索引 查找索引(维度表)的名称。 不适用
查找映射字段 lookup-index 中的映射键,类似于右表的 join 键。您可以使用逗号指定多个 lookup-mapping-field 值。 不适用
源映射字段 源(左侧)中的映射键,类似于左侧的 join 键。 查找映射字段
replace | append 输出策略。指定 replace 时,lookup-index 字段中的匹配值会覆盖结果中的值。如果指定 appendlookup-index 字段中的匹配值只会追加到结果中缺失的值。 替换
输入字段 lookup-index 中的一个字段,匹配值将应用于结果输出。您可以使用逗号指定多个 input-field 值。如果您未指定任何 input-field,则 lookup-index 中除 lookup-mapping-field 之外的所有字段的匹配值都将应用于结果输出。 不适用
输出字段 一个输出字段。您可以指定零个或多个 output-field 值。如果您将 output-field 指定为源查询中已存在的字段名,其值将被来自 input-field 的匹配值替换或追加。如果 output-field 中指定的字段是一个新字段,则结果中将应用一个扩展的新字段。 输入字段

以下示例使用 workerswork_information 索引。

workers:

ID 名称 职业 国家 薪水
1000 Jake 工程师 英格兰 100000
1001 Hello 艺术家 美国 70000
1002 John 医生 加拿大 120000
1003 David 医生 不适用 120000
1004 David 不适用 加拿大 0
1005 Jane 科学家 加拿大 90000

work_information:

UID 名称 部门 职业
1000 Jake IT 工程师
1002 John DATA 科学家
1003 David 人力资源部 医生
1005 Jane DATA 工程师
1006 Tom 销售 艺术家

示例 1:查找员工并返回对应的部门

以下示例查找员工并返回对应的部门

source = workers | lookup work_information uid as id append department
ID 名称 occupation 国家 薪水 部门
1000 Jake 工程师 英格兰 100000 IT
1001 Hello 艺术家 美国 70000
1002 John 医生 加拿大 120000 DATA
1003 David 医生 120000 人力资源部
1004 David 加拿大 0
1005 Jane 科学家 加拿大 90000 DATA

示例 2:查找员工并替换其职业和部门

以下示例查找员工并使用他们的 work_information 替换其职业和部门

source = workers | lookup work_information uid as id, name
ID 名称 occupation 国家 薪水 部门
1000 Jake 工程师 英格兰 100000 IT
1001 Hello null 美国 70000 null
1002 John 科学家 加拿大 120000 DATA
1003 David 医生 null 120000 人力资源部
1004 David null 加拿大 0 null
1005 Jane 工程师 加拿大 90000 DATA

示例 3:查找员工并创建新的职业字段

以下示例查找员工并将其 work_information 中的职业作为新字段追加

source = workers | lookup work_information name replace occupation as new_occupation
ID 名称 occupation 国家 薪水 new_occupation
1000 Jake 工程师 英格兰 100000 工程师
1001 Hello 艺术家 美国 70000 null
1002 John 医生 加拿大 120000 科学家
1003 David 医生 null 120000 医生
1004 David null 加拿大 0 医生
1005 Jane 科学家 加拿大 90000 工程师

限制

lookup 命令仅在 plugins.calcite.enabled 设置为 true 时才有效。