在U-SQL中编写和使用自定义代码–用户定义函数

Visual Studio博客

在我的上一篇博客帖子,我引入了U-SQL作为新的大数据查询语言,用于Azure数据湖这将SQL的优点与您自己代码的表达能力结合在一起。今天我们宣布可用性Azure数据湖的公共预览。现在您可以在Visual Studio中尝试U-SQL,并在存储区中的大量数据以及关系存储区(如Azure SQL Database)中运行它。在这篇博客文章中,我将深入探讨如何使用自定义代码扩展U-SQL查询。

U-SQL的主要价值之一是添加用C#编写的用户特定代码有多容易。由于U-SQL的类型系统是基于C#的,并且这些类型实例上的U-SQL标量表达式语言是C#表达式语言,因此很容易使用C#语言和。NET框架和U-SQL中的程序集。

U-SQL的C#集成

U-SQL在其类型系统和标量表达式语言方面对C#的核心依赖使查询编写器能够访问C#和CLR库中丰富的类、方法、函数、运算符和类型

首先,除了赋值运算符(=、+=等)之外,所有C#运算符在U-SQL标量表达式中都是有效的。特别是,所有比较运算符,如==、!=、<、>、,三元比较条件?真表达式:假表达式,空合并运算符??支持。即使使用=>的lambda表达式也可以在U-SQL表达式中使用。

U-SQL与C#Roslyn编译器事实上,U-SQL集成可能是C#Roslyn编译器平台中最复杂的应用程序。

C#代码可以通过多种方式扩展U-SQL表达式:

  • 提供内联C#表达式在U-SQL脚本中:如果需要应用一组小的C#方法来处理其中一个标量值,这通常是有意义的。例如,字符串类型方法或数学函数。
  • 写入用户定义函数在C#程序集中并在U-SQL脚本中引用它们:如果函数的逻辑要求C#的全部功能超出其表达式语言(如过程逻辑或递归),则对于更复杂的函数来说,这是首选方法。
  • 写入用户定义的聚合器在C#程序集中并在U-SQL脚本中引用它们:通过提供用户定义的聚合器,可以使用GROUPBY子句将自定义聚合逻辑插入到U-SQL的聚合处理中。
  • 写入用户定义运算符在C#程序集中并在U-SQL脚本中引用它们:用户定义运算符(UDO)是U-SQL的自定义代码行集运算符。它们是用C#编写的,能够生成、处理和使用行集。

对于用户定义的函数、聚合器和运算符,必须使用CREATE assembly(U-SQL)将C#程序集加载到U-SQL元数据目录中,然后使用REFERENCE ASSEMBOLY在脚本中引用面向Visual Studio的Azure数据湖工具让注册过程变得轻而易举,甚至可以提供所谓的代码隐藏体验,您只需编写代码并提交脚本,工具就可以处理所有管道。

在今天的博客帖子中,让我们看看这个例子我一个月前介绍的并深入了解内联C#表达式以及使用U-SQL编写用户定义的C#表达式和函数的经验。

U-SQL内联C#表达式

让我们快速回忆一下这个示例:数据是我所有推特、转发和提及的推特历史记录,它位于我的Azure data Lake Store中的一个CSV文件中:

Azure Data Lake存储中的数据

回到我们的例子,我现在想添加关于推文中提到的人的更多信息,并扩展我的聚合,以返回我的推文网络中的人创作推文的频率以及他们被提及的频率。在前一篇文章中,您看到了以下U-SQL脚本的简化版本(请阅读U-SQL的原理和语句处理在上一篇文章中):

U-SQL代码

上面脚本突出显示的部分显示了U-SQL期望并接受C#表达式的一些位置。如您所见,您可以在EXTRACT和OUPUT的USING子句、SELECT子句和WHERE子句以及GROUP BY子句、ORDER BY子句和EXPLODE函数中使用C#表达式,尽管在本例中,我们只是在后面的两种情况中引用列名。

集成的一个重要方面是,C#表达式可以无缝地完全访问查询表达式中的标量值,因为它们是用C#类型键入的。

第6行和第32行中的EXTRACT和OUPUT的USING子句使用C#表达式生成用户定义的运算符实例。上面的两个内置表达式是对工厂方法的调用,它们分别返回提取器和输出器实例。我们将在未来的博客文章中详细讨论用户定义的操作符。

让我们更详细地看一下第8行中的C#表达式:

新SQL。数组<string>(tweet.Split(“”)。其中(x=>x.StartsWith(“@”))

这是使用C#的一个很好的例子:U-SQL内置类型SQL。阵列<T>实际上是一种C#对象类型,它提供了预期的SQL/Hive功能,而没有现有C#数组类型的副作用更新功能。您只需使用C#的new操作符创建一个新实例。通过简单地对用一串键入以将其分解为单词。不用再奇怪,在普通SQL方言中,您从哪里获得了某种字符串类型的功能:您可以轻松掌握CLR的全部功能!

它变得更好了。这个拆分方法返回IEnumerable<字符串>因此,可以使用LINQ表达式并使用lambda表达式作为谓词来完成任何进一步的处理,例如仅过滤tweet单词中的提及。现在用您的标准SQL语言来尝试一下!

让我们也看看哪里第21行中的条款。同样,我可以简单地提供引用行集中列的C#表达式。此上下文中的表达式必须产生类型为的值布尔现在C#有两值逻辑,而不像SQL那样有三值逻辑。因此,比较r!=无效的将返回真的如果第页不是无效的虚假的如果是的话无效的。此外,通过使用C#逻辑运算符&&,我得到了C#的执行顺序被保留的保证,更重要的是,如果第一个比较结果为false,则不会执行正确的比较。

U-SQL和Visual Studio的代码绑定功能

上一篇博客文章我展示了代码隐藏功能,这些功能将在提交时自动将相关的.cs文件中的代码部署到服务。为了能够引用U-SQL中的方法、类型和函数,类必须定义为公众的对象需要定义为静态公共.

U-SQL代码

该工具实际上执行以下步骤:

  1. .cs文件将编译为程序集文件。
  2. 用户的U-SQL脚本增加了一个标题,该标题添加了一个CREATE ASSEMBLY语句,该语句将在U-SQL元数据目录中创建汇编文件二进制内容。
  3. 它还在脚本末尾添加了一个清理,该清理将使用DROP assembly语句删除注册的程序集。

以下显示了工具使用代码隐藏标头提交的修改后的脚本:

形象

U-SQL程序集

我还可以自己显式地在U-SQL元数据目录中将代码部署并注册为程序集。这允许我和其他人在将来的脚本中使用代码。如果您有更复杂的代码需要单独维护,那么它也是管理用户定义函数、聚合器和操作符的首选方法,您可能希望在其中包含可能已在其他上下文中编写的现有代码(如XML或JSON库)或者甚至调用外部可执行文件(这也是稍后博客文章的主题)。

由于我在前一篇文章中展示了如何使用程序集的代码,让我再多谈谈U-SQL中的程序集管理。

与SQL Server等关系数据库类似,U-SQL提供元数据目录并支持标准数据库对象。其中一个对象是程序集元数据对象。通过使用CREATE ASSEMBLY语句,可以在数据库中注册程序集。程序集是作用域为数据库的对象,程序集DLL文件被放置在主Azure Data Lake Storage帐户的目录文件夹内的相关数据库文件夹内的程序集文件夹中。

除了存储程序集之外,您还可以指定将与程序集一起存储并在引用程序集时包含的其他文件。CREATE ASSEMBLY语句语法如下所示(请参见U-SQL语言参考文档更多详细信息):

创建装配语句:=
“CREATE”“ASSEMBLY”“['IF”“NOT”“EXISTS”]程序集名称
“FROM”程序集源
['WITH''附加文件''='
'('程序集_Additional_File_List')']。

组件名称:=引用或未引用标识符。

程序集源(_S):=
Static_String_Expression|lexical_binary_value。

说到引用程序集,U-SQL有一小部分预加载的系统程序集和命名空间,包括System和System。林克。该集合保持较小,以降低编译时间和作业的资源利用率。如果要引用不同的系统程序集,可以在添加system的以下语句中包含它们。Xml代码:

参考系统组件[SYSTEM.Xml];

接下来是什么?

Azure数据湖的公开预览已于今天开放。所以拜托 注册用于加入Azure Data Lake Analytics预览、和给我们你的反馈!

在未来的博客文章中,我将深入探讨用户定义的操作符。请在评论中或通过上面的反馈链接让我知道您想了解的其他U-SQL主题,例如文件集、元数据对象、联合查询等。

另外,前往我们的Azure数据湖文档中心阅读更多内容并观看我们的第9频道Azure Data Lake视频系列.

 

剪辑_图像007

Michael Rys(@MikeDoesBigData),微软大数据首席项目经理

Michael自20世纪80年代以来一直从事数据处理和查询语言的工作。除此之外,他一直代表微软参加XQuery和SQL设计委员会,并将SQL Server超越了与XML、地理空间和语义搜索的关系。目前,他正在研究大数据查询语言,如SCOPE和U-SQL,而不是在水下和家人一起享受时光,或是在独裁统治下。

0条评论

讨论结束。

反馈usabilla图标