高级搜索
高级搜索
背景
Atlas 中的高级搜索也称为基于 DSL 的搜索。
领域特定语言(DSL)是一种具有简单结构的语言,可帮助用户浏览 Atlas 数据仓库。其语法在一定程度上借鉴了关系数据库领域中广为使用的结构化查询语言(SQL)。
DSL 的优势:
- 对实现层面的数据库概念进行抽象,因此无须了解底层图数据库的结构。
- 为用户提供一种抽象,只要了解数据集中的类型及其关系,即可检索数据。
- 支持指定所需的输出方式。
- 语法中考虑了分类(classification)的使用。
- 提供对结果进行分组和聚合的方式。
在后续示例中,我们将使用快速入门数据集。该数据集足够全面,可用于演示该语言的各种功能。
有关语法的详细信息,请参阅 GitHub 上的 Atlas DSL 语法(Antlr G4 格式):GitHub
使用高级搜索
在 Atlas 界面中,选择左侧搜索面板中的“高级”。
请注意“按查询搜索”框下方的收藏的搜索面板。与基本搜索一样,高级搜索同样可以保存。
领域特定语言简介
DSL 使用熟悉的类 SQL 语法。
从高层次来看,查询采用 from-where-select 格式。可以添加 grouby、orderby、limit 等附加关键字来影响输出。下面我们将看到相关示例。
From 子句
指定 from 子句是必需的,但使用 from 关键字本身是可选的。from 子句中指定的值作为查询其余部分获取输入的源或起点。
示例:检索类型为 DB 的所有实体:
DB
from DB在缺少用于在源上进行过滤的 where 子句时,from 子句获取的数据集就是数据库中的全部内容。根据数据库中数据量的大小,这有可能使服务器不堪重负。因此,查询处理器会添加 limit 子句并为其设置默认值。详见 limit 子句一节。
Where 子句
where 子句用于对数据集进行过滤。这是通过在 where 子句中使用条件来实现的。
一个条件由一个标识符、后接一个运算符、再后接一个字面量组成。字面量必须用单引号或双引号括起来。例如,name = "Sales"。标识符可以是 from 子句中所指定类型的属性名称,也可以是一个别名。
示例:检索具有特定名称(例如 time_dim)的 Table 类型实体。
from Table where name = 'time_dim'可以通过 and、or 运算符组合多个条件。
示例:检索类型为 Table、名称为 time_dim 或 customer_dim 的实体:
from Table where name = 'time_dim' or name = 'customer_dim'基于值列表进行过滤时,只需在方括号中指定这些值即可。值数组是指用方括号括起来的一组值。这是在标识符上指定 OR 子句的一种简单方式。
请注意,在同一属性上使用多个 OR 子句可能会导致效率低下。另一种方式是使用值数组,如下例所示。
示例:上例中的查询可以使用值数组改写为如下形式。
from Table where name = ["customer_dim", "time_dim"]使用 LIKE 运算符的条件支持使用通配符(如 \* 或 ?)进行过滤。示例:要检索名称以 _dim 结尾的 Table 类型实体:
from Table where name LIKE '*_dim'还可以使用其他形式的正则表达式。
示例:检索名称以 R 开头、后跟任意 3 个字符、接着是 rt、然后是至少 1 个字符、最后是零个或任意数量字符的 DB。
DB where name like "R???rt?*"示例:查找某张表中的所有列。
Column where table.name="sales_fact"示例:查找某列对应的所有表。
Table where columns.name="sales"示例:检索所有类型为 Table、被打上 Dimension 分类标记,且其属性 priority 为 'high' 的实体
Table where Dimension.priority = "high"使用日期字面量
字面量中使用的日期需要采用 ISO 8601 格式指定。
此格式的日期遵循以下表示法:
- yyyy-MM-ddTHHss.SSSZ。即:年-月-日,后跟时-分-秒-毫秒形式的时间。日期和时间之间需要用 'T' 分隔,末尾应以 'Z' 结束。
- yyyy-MM-dd。即:年-月-日。
示例:表示 2017 年 12 月 11 日凌晨 2:35 的日期。
2017-12-11T02:35:0.0Z示例:检索在 2017 年至 2018 年间创建的、类型为 Table 的实体。
from Table where createTime < '2018-01-01' and createTime > '2017-01-01'使用布尔字面量
可以在查询中使用布尔类型的实体属性。
示例:检索类型为 hdfspath 的实体,其属性 _isFile 的值为 true,且名称为 Invoice。
from hdfs_path where isFile = true or name = "Invoice"布尔字面量的有效值为 'true' 和 'false'。
属性的存在性
has 关键字可以配合 where 子句使用,也可以单独使用。它用于检查实体中是否存在某个属性。
示例:检索具有 locationUri 属性的 Table 类型实体。
Table has locationUri
from Table where Table has locationUriSelect 子句
如果你注意到网页上显示的输出,它以表格形式展示,每一行对应一个实体,列则是该实体的属性。Select 子句允许选择你感兴趣的实体属性。
示例:检索类型为 Table 的实体及其部分属性:
from Table select owner, name, qualifiedName示例:检索特定表的 Table 类型实体及其部分属性。
from Table where name = 'customer_dim' select owner, name, qualifiedName要显示更有意义的列标题,可以使用 as 子句为列添加别名。
示例:将列标题显示为「Owner」、「Name」和「FullName」。
from Table select owner as Owner, name as Name, qualifiedName as FullName关于 Select 子句的说明
由于使用 select 子句较为复杂,在使用时请牢记以下几条规则:
- 适用于所有直接属性。
- 适用于直接属性,以及对直接属性的聚合。
- 引用属性不能与直接属性混合使用。
示例:检索名为 'Sales' 的 Table 类型实体,并显示其引用实体 DB 的 'name' 和 'owner' 属性。
Table where name = 'abcd' select DB.name, DB.owner当前实现不允许以下操作:
Table where name = 'abcd' select DB.name, Table.name基于分类的筛选
若要根据分类检索实体,查询需使用 is 或 isa 关键字。
示例:检索所有被标记为 Dimension 分类的 Table 类型实体。
from Table isa Dimension由于 from 是可选的,且 is(或 isa)含义相同,因此以下查询返回相同的结果:
Table is Dimensionis 和 isa 子句也可以在 where 条件中使用,例如:
from Table where Table isa Dimension要搜索所有具有某个特定分类的实体,直接使用该分类的名称即可。
示例:检索所有具有 Dimension(维度)分类的实体。
Dimension要在 where 子句中添加过滤条件,以搜索所有具有特定分类及其属性的实体。
示例:检索所有被标记为 Dimension 分类、且其属性 priority 值为 'high' 的实体。
Dimension where Dimension.priority = "high"###非基本类型属性过滤
到目前为止,我们讨论的 where 子句都是基于基本类型的。本节将介绍如何使用非基本类型的属性进行过滤。
基于关系的过滤
在该模型中,数据库(DB)的建模方式使其知道自己所包含的所有表(Table)。而表(Table)虽然知道数据库(DB)的存在,但并不了解系统中其他所有的 Table 实例。每个表都维护着对其所属 DB 的引用。
Hive 数据模型中也存在类似的结构。
示例:检索属于名为 'Sales' 的数据库的所有 Table 实例:
Table where db.name = "Sales"示例:检索属于名为 'Sales' 的数据库、且列名以 'customer' 开头的所有 Table 实例:
Table where db.name = "Sales" and columns.name like "customer*"实体 Column 也是以类似方式建模的。每个 Table 实体都有向外的边,指向与表中各列相对应的 Column 实体实例。
示例:检索某个给定 Table 的所有 Column 实体。
Table where name = "time_dim" select columns将显示每个 Column 实体类型的属性。
基于术语表条目的过滤
要根据术语表条目检索实体,查询会使用 hasTerm 关键字。
要搜索具有特定术语表条目的实体,用户需要添加完全限定名称,即 {termName}@{glossaryName}。如果用户只添加条目名称,则无论该条目属于哪个术语表,都会返回具有该条目名称的所有实体。
示例:要检索具有术语表条目 savingsAccount@Banking 的所有 Table 类型实体,以下是可能的实现方式。
from Table hasTerm "savingsAccount@Banking"
Table hasTerm "savingsAccount@Banking"
Table hasTerm "savingsAccount"
Table where Table hasTerm "savingsAccount@Banking"示例:检索类型为 Table(表)、具有术语 savingsAccount@Banking 且名称为 'customer' 的所有实体。
from Table hasTerm "savingsAccount@Banking" and name = "customer"示例:检索所有类型为 Table、具有术语表术语 savingsAccount@Banking,或者带有 'Dimension' 分类且列名以 'customer' 开头的实体。
from Table hasTerm "savingsAccount@Banking" or Table isA Dimension and (columns.name like "customer*")limit 与 offset 子句
查询往往会产生大量结果。若要限制查询返回的结果数量,可以使用 limit 和 offset 子句。
示例:仅从结果集中检索 5 个实体。
Column limit 5offset 子句用于获取偏移量之后的结果。
示例:跳过前 10 条记录后,仅获取结果集中的 5 个实体。
Column limit 5 offset 10limit 与 offset 子句通常一起指定。
如果查询中未指定 limit 子句,则会在查询中添加一个带有默认限制(通常为 100)的 limit 子句。这样可以防止查询意外获取大量结果。
offset 子句适用于用户界面中显示结果的场景:界面上只显示结果集中的少量结果,当用户翻到下一页时再获取更多结果。
结果排序
orderby 子句允许对结果进行排序。默认按升序排序。该子句中只能使用直接属性。
排序方式可通过以下方式更改:
- ASC 按升序排序。这是默认方式。如果 orderby 子句之后未指定排序方式。
- DESC 按降序排序。需要在 orderby 子句之后显式指定。
示例:检索类型为 Column 且按 name 属性升序排序的实体。
from Column orderby name
from Column orderby name asc示例:结果与上面相同,只是按降序排序。
from Column orderby name desc示例:检索类型为 Column 的实体,按名称过滤,并关联到 'savingsAccount@Banking' 术语表词条,同时使用 name 属性按升序排序。
from Column hasTerm "savingsAccount@Banking" and name = "customer_id" orderby name asc聚合函数
我们来看看聚合函数:
- sum:在结果集中,对所指定属性的值求和。
- min:在结果集中,求所指定属性的最小值。
- max:在结果集中,求所指定属性的最大值。
- count:求 group by 子句所指定的条目数量。
这些函数仅适用于直接属性。
其他示例请参见 分组结果 一节。
count 关键字
显示结果集中的条目数量。
示例:要了解某种类型的 Column 有多少个实体。
Column select count()示例:与上面相同,但使用了别名。
Column select count() as Cols示例:查找某个数据库中的表数量。
Table where db.name = "Reporting" select count()示例:查询与特定类型 “Table” 关联的术语数量。
Table hasTerm "savingsAccount@Banking" select count() as termsmax 关键字
使用该关键字可以检索实体某个属性的最大值。
示例:获取 Table 实体 createTime 属性的最新创建值。
Table select max(createTime)min 关键字
使用此关键字可以检索实体某个属性的最小值。
示例:获取 Table 实体 createTime 属性中最早创建的值。
Table select min(createTime)结果分组
groupby 子句使用指定的属性对结果进行分组。
示例:检索类型为 Table 的实体,使属于同一所有者(owner)的表归为一组(按所有者分组)。
Table groupby(owner)虽然 groupby 可以不配合 select 使用,但如果在 select 子句中使用了聚合函数,groupby 子句就变成了必需的,因为聚合函数是对分组进行运算的。
示例:检索 Table 类型的实体,从中获知最近创建的实体。
Table groupby(createTime) select owner, name, max(createTime)示例:检索类型为 Table 的实体,这样我们就知道最旧的实体。
Table groupby(createTime) select owner, name, min(createTime)示例:了解每个所有者拥有的实体数量。
Table groupby(owner) select owner, count()使用系统属性
在 Atlas 中定义的每个类型默认都会获得若干属性。这些属性用于对实体进行内部记录管理。所有系统属性都以 __(双下划线)为前缀,以便将其与其他属性区分开来。以下是系统属性:
__guidAtlas 中的每个实体都会被分配一个全局唯一标识符(简称 GUID)。__modifiedBy最后修改该实体的用户名称。__createdBy创建该实体的用户名称。__state实体的当前状态,详见下文。__timestamp实体创建时的时间戳(以整数表示的日期)。__modificationTimestamp实体最后一次修改时的时间戳(以整数表示的日期)。
实体的状态
Atlas 中的实体可以处于以下状态:
- ACTIVE 这是实体在可用并被系统使用时所处的状态。搜索时默认可检索到处于该状态的实体。
- DELETED 当实体被删除时,其状态被标记为 DELETED。处于该状态的实体不会出现在搜索结果中,需要显式发起请求才能检索到该实体。
在查询中使用系统属性
示例:检索所有已被删除的实体。
Asset where __state = "DELETED"示例:检索实体 GUID。
Table select __guid示例:检索多个系统属性。
hive_db select __timestamp, __modificationTimestamp, __state, __createdBy高级搜索 REST API
这些操作相关的模型:
V2 API
使用 DSL 搜索获取结果
| 示例 | 参见下方的「示例」部分。 |
|---|---|
| URL | api/atlas/v2/search/dsl |
| 方法 | GET |
| URL 参数 | query:符合 DSL 语法的查询语句。 |
| typeName:要检索的实体的类型名称。 | |
| classification:与该类型或查询关联的分类。 | |
| limit:结果集中条目的最大数量。 | |
| offset:条目在结果集中的起始索引。 | |
| 数据参数 | 无 |
| 成功响应 | 返回的 JSON 将对应 AtlasSearchResult。 |
| 错误响应 | 系统内部处理的错误将以 AtlasBaseException 的形式返回。 |
| 方法签名 | @GET |
| @Path("/dsl") | |
| @Consumes(Servlets.JSON_MEDIA_TYPE) | |
| @Produces(Servlets.JSON_MEDIA_TYPE) |
示例
curl -X GET -u admin:admin -H "Content-Type: application/json" "http://localhost:21000/api/atlas/v2/search/dsl?typeName=Table"
curl -X GET -u admin:admin -H "Content-Type: application/json" "http://localhost:21000/api/atlas/v2/search/dsl?typeName=Column&classification=PII"
curl -X GET -u admin:admin -H "Content-Type: application/json" "http://localhost:21000/api/atlas/v2/search/dsl?typeName=Table&classification=Dimension&limit=10&offset=2"
curl -X GET -u admin:admin -H "Content-Type: application/json" "http://localhost:21000/api/atlas/v2/search/dsl?query=Table%20isa%20Dimension"
curl -X GET -u admin:admin -H "Content-Type: application/json" "http://localhost:21000/api/atlas/v2/search/dsl?query=Table%20isa%20Dimension&limit=5&offset=2"实现方式
Atlas 中 DSL 实现所遵循的一般方法可概括为以下步骤:
- 解析器解析传入查询的语法。
- 对解析成功的查询生成抽象语法树。
- 使用访问者模式"遍历"语法树。
- 树中的每一次"访问"都会在 Gremlin 管道中添加一个步骤。
- 完成后,使用 Gremlin 脚本引擎执行生成的脚本。
- 查询产生的结果(如有)会被处理并封装在 AtlasSearchResult 结构中。
与主分支及早期版本的差异
以下子句已不再支持:
- path
- loop
参考资源
- Antlr 书籍。
- Antlr 快速入门。
- GitHub 上的 Atlas DSL 语法定义 AtlasDSLParser.g4(Antlr G4 格式)。
评论
登录后参与评论
KnowForge