文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。
Apache Atlas 框架是一套可扩展的核心基础治理服务,使企业能够有效、高效地满足 Hadoop 中的合规性要求,并支持与整个企业数据生态系统集成。这将通过使用规范和取证模型,以及技术和运营审计以及由业务分类元数据丰富的沿袭,在 Hadoop 中提供真正的可视性。它还使任何元数据使用者能够互操作,而无需彼此独立的接口——元数据存储是通用的。通过利用 Apache Ranger 来维护元数据的准确性,以防止在运行时对数据进行未经授权的访问。安全性基于角色 (RBAC) 和属性 (ABAC)。
高级搜索
Advanced Search
背景
Atlas 中的高级搜索也被称为基于 DSL 的搜索。
领域特定搜索(DSL)是一种使用简单结构的语言,帮助用户在 Atlas 数据仓库中进行导航。其语法松散地模仿了关系数据库世界中流行的结构化查询语言(SQL)。
DSL 的优势:
- 抽象实现层的数据库结构,避免必须了解底层图数据库构造的必要性。
- 为用户提供一个抽象层,使其仅通过了解其数据集中的类型及其关系即可检索数据。
- 提供指定所需输出的方式。
- 语法中已考虑使用分类。
- 提供对结果进行分组和聚合的方法。
我们将在后续示例中使用快速入门数据集。该数据集足够全面,可用于演示该语言的各种功能。
有关语法的详细信息,请参阅 GitHub 上的 Atlas DSL 语法(Antlr G4 格式)。
使用高级搜索
在 Atlas UI 中,选择左侧搜索窗格中的“高级”。
请注意 搜索查询 框下方的 收藏搜索 窗格。与 基本搜索 类似,也可以保存 高级搜索。
领域特定语言简介
DSL 使用熟悉的类 SQL 语法。
在高层级上,查询具有 from-where-select 格式。可以添加额外的关键字如 groupby、orderby、limit 来影响输出。我们将在下面看到这些示例。
From 子句
指定 from 子句是强制性的。使用 from 关键字本身是可选的。from 子句中指定的值充当其余查询获取输入的源或起点。
示例:检索类型为 DB 的所有实体:
DB
from DB
在没有 where 进行源过滤的情况下,from 子句获取的数据集是数据库中所有内容。根据数据库中数据的大小,有可能使服务器不堪重负。因此,查询处理器会添加一个带默认值的 limit 子句。有关详细信息,请参见 limit 子句部分。
Where 子句
where 子句允许对数据集进行过滤。这是通过在 where 子句中使用条件来实现的。
条件是一个标识符,后跟一个运算符,再后跟一个字面量。字面量必须用单引号或双引号括起来。例如,name = “Sales”。标识符可以是 from 子句中指定类型的属性名称或别名。
示例:检索类型为 Table 且名称为 time_dim 的实体:
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 运算符的条件允许使用通配符 ‘*’ 或 ‘?’ 进行过滤。
示例:检索类型为 Table 且名称以 ‘_dim’ 结尾的实体:
from Table where name LIKE '*_dim'
也可以使用其他形式的正则表达式。
示例:检索名称以 R 开头,后跟任意 3 个字符,再后跟 rt,再后跟至少 1 个字符,再后跟 0 个或任意数量字符的 DB。
DB where name like "R???rt?*"
示例:查找 Table 中的所有列。
Column where table.name="sales_fact"
示例:查找列对应的所有 Table。
Table where columns.name="sales"
示例:检索所有被标记为 Dimension 分类且其属性 priority 为 ‘high’ 的类型为 Table 的实体
Table where Dimension.priority = "high"
使用日期字面量
查询中使用的日期需要使用 ISO 8601 格式指定。
此格式的日期遵循以下表示法:
- yyyy-MM-ddTHH:mm:ss.SSSZ。即,年-月-日,后跟以小时-分钟-秒-毫秒表示的时间。日期和时间需要用 ‘T’ 分隔。以 ‘Z’ 结尾。
- yyyy-MM-dd。即,年-月-日。
示例:日期表示 2017 年 12 月 11 日凌晨 2:35。
2017-12-11T02:35:0.0Z
示例:检索类型为 Table 且在 2017 年和 2018 年之间创建的实体。
from Table where createTime < '2018-01-01' and createTime > '2017-01-01'
使用布尔字面量
可以在查询中使用类型为 boolean 的实体属性。
示例:检索类型为 hdfs_path 且属性 isFile 设置为 true 且名称为 Invoice 的实体。
from hdfs_path where isFile = true or name = "Invoice"
布尔字面量的有效值为 ‘true’ 和 ‘false’。
属性的存在性
has 关键字可以与 where 子句一起使用或不使用。它用于检查实体中是否存在某个属性。
示例:检索类型为 Table 且具有属性 locationUri 的实体。
Table has locationUri
from Table where Table has locationUri
Select 子句
如果您注意到网页上显示的输出,它会以表格形式显示,每行对应一个实体,列是该实体的属性。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 子句的复杂性,使用 select 子句时需要记住以下规则:
- 适用于所有 immediate 属性。
- 适用于 immediate 属性以及在 immediate 属性上的聚合。
- 不能混合使用 referred 属性和 immediate 属性。
示例:检索类型为 Table 且名称为 ‘Sales’ 的实体,并显示 referred 实体 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 Dimension
is 和 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 实例。每个 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}。如果用户仅添加术语名称,则无论术语位于哪个词汇表中,都将返回具有特定术语名称的所有实体。
示例:要检索类型为 Table 且具有术语 savingsAccount@Banking 的所有实体,以下是可能的方式。
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 5
offset 子句在偏移值之后检索结果。
示例:在跳过前 10 个结果后,仅检索结果集中的 5 个实体。
Column limit 5 offset 10
limit 和 offset 子句通常一起指定。
如果查询中未指定 limit 子句,则会向查询添加一个带默认限制(通常为 100)的 limit 子句。这可以防止查询无意中获取大量结果。
offset 子句在用户界面中显示结果时很有用,其中结果集中只显示少量结果,并且当用户前进到下一页时会获取更多结果。
结果排序
_orderby* 子句允许对结果进行排序。结果默认按升序排序。仅 immediate 属性可用于此子句。
可以通过以下方式更改排序:
- ASC 按升序排序。这是默认的。如果 orderby 子句后未指定排序。
- DESC 按降序排序。需要在 orderby 子句后明确指定。
示例:使用 name 属性按升序检索类型为 Column 的实体。
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 子句指定的项目数量。
这些仅适用于 immediate 属性。
其他示例见“结果分组”部分。
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 terms
max 关键字
使用此关键字可以检索实体属性的最大值。
示例:获取 Table 实体的 createTime 属性的最近创建值。
Table select max(createTime)
min 关键字
使用此关键字可以检索实体属性的最小值。
示例:获取 Table 实体的 createTime 属性的最早创建值。
Table select min(createTime)
结果分组
_groupby* 子句使用指定属性对结果中的结果进行分组。
示例:检索类型为 Table 的实体,使得属于某个所有者的表在一起(按所有者分组)。
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 中定义的每种类型都会默认获得一些属性。这些属性有助于实体内部记账。所有系统属性都以 ‘__’(双下划线)为前缀。这有助于将它们与其他属性区分开来。
以下是系统属性:
- __guid Atlas 中的每个实体都会分配一个全局唯一标识符(简称 GUID)。
- __modifiedBy 最后修改实体的用户的名称。
- __createdBy 创建实体的用户的名称。
- __state 实体的当前状态。详见下文。
- __timestamp 实体创建时的 timestamp(以整数表示的日期)。
- __modificationTimestamp 实体最后修改时的 timestamp(以整数表示的日期)。
实体状态
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 的实现所遵循的一般方法可以列举为以下步骤:
- 解析器解析传入查询的语法。
- 对于成功解析的查询,生成抽象语法树。
- 使用 visitor 模式“遍历”语法树。
- 树中的每个“访问”都会在 Gremlin 管道中添加一个步骤。
- 完成后,生成的脚本将使用 Gremlin 脚本引擎执行。
- 查询生成的结果(如果有)将被处理并打包到 AtlasSearchResult 结构中。
Master 与早期版本之间的差异
以下子句不再受支持:
- path
- loop
资源
- Antlr 图书。
- Antlr 快速入门。
- GitHub 上的 Atlas DSL 语法(Antlr G4 格式)。
风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。