高级搜索
背景
Atlas 中的高级搜索也称为基于 DSL 的搜索。
领域特定搜索(DSL)是一种具有简单构造的语言,帮助用户浏览 Atlas 数据仓库。其语法在很大程度上借鉴了关系数据库领域中广为流行的结构化查询语言(SQL)。
DSL 的优势:
- 抽象了实现层面的数据库概念,避免了用户必须了解底层图数据库概念的需要。
- 为用户提供了一种抽象,使其只需了解数据集中的类型及其关系即可检索数据。
- 提供了指定所需输出的方式。
- 语法中考虑了分类(classification)的使用。
- 提供了对结果进行分组和聚合的方式。
接下来的示例中我们将使用快速入门数据集。该数据集足够全面,可用于演示该语言的各种功能。
有关语法的详细信息,请参阅 GitHub 上的 Atlas DSL 语法 GitHub(Antlr G4 格式)。
使用高级搜索
在 Atlas UI 中,在左侧的搜索面板中选择“高级(Advanced)”。
请注意 按查询搜索(Search By Query) 框下方的 收藏的搜索(Favorite Searches) 面板。与 基础搜索(Basic Search) 一样,高级搜索(Advanced Searches) 也可以保存。
领域特定语言简介
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 Dimensionfrom 子句是可选的,且 *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 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' 术语表词条,并按升序排列。
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 的表归为一组(按 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 中定义的每个类型默认都会获得若干属性。这些属性有助于对实体进行内部簿记管理。所有系统属性都以 \_\_(双下划线)作为前缀,这样便于将其与其他属性区分开来。系统属性如下:
- __guid Atlas 中的每个实体都会被分配一个全局唯一标识符(简称 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
参考资源
评论
登录后参与评论
KnowForge