Massive Data处理一直是云计算中很重要的一个环节.目前像Google,Yahoo在相关方面都有自己专有的技术.例如Google的基于MapReduce的Sawzall语言.和Yahoo基于Hadoop的Pig。
Cosmos是微软的一个运行在大规模服务器集群上的分布式技术平台.专门用来存储和分析Massive Data.有了SCOPE,相信微软自己的云计算架构将会更有吸引力.不同于Google,和Yahoo的是微软的SCOPE语言虽然像SQL语句,但其实是来自C#语言扩展。
什么是Scope?,首先:
1.Scope is the Query Language for Cosmos
2.Scope Is Not SQL
Scope 中的数据类型:
bool |
Long |
byte[] |
Ulong |
binary (an alias for byte[]) |
Float |
byte |
Double |
sbyte |
decimal |
Char |
String |
Guid |
Short |
Int |
ushort |
Uint |
User-Defined Types |
Scope基本语法
逻辑运算符:AND(与,不能用 &&),OR(或,不能用 ||),==(等于,不能用 =)
SELECT:与SQL相同,通过 AS 关键字给列分配名称。
rs1 = SELECT Market, DwellTime + 1.0 AS DwellTime2 FROM searchlog;
WHERE:过滤输入的行数据;
rs1 = SELECT Start, Market, DwellTime, DwellTime /60.0 AS DwellTimeInMinutes FROM searchlog; rs2 = SELECT * FROM rs1 ;
HAVING:过滤输出的行数据;
rs1 = SELECT Start, Market, DwellTime/60.0 AS DwellTimeInMinutes FROM searchlog ;
TOP n:获取前n行记录;
rs1 = Market, DwellTime FROM searchlog;
DISTINCT:用法与SQL相同;
rs1 = SELECT DISTINCT Market
FROM searchlog;
ORDER BY + ASC /DESC:
rs1 = SELECT Start, Market, DwellTime FROM searchlog ORDER BY DwellTime ASC;
RANK:列序号;
rs1 = SELECT RANK AS RowNumber, Start, Market FROM searchlog ORDER BY Start;
聚集函数:
ARGMAX AVG COUNT COUNTIF FIRST LAST LIST MAX MIN SUM VAR STDE
ARGMAX(a,b): 查找a列的最大值,并返回相应的b列的值。
UNION DISTINC:后续
UNION ALL:后续
INSERT DISTINC:后续
INSERT ALL:后续
EXCEPT DISTINC:后续
EXCEPT ALL:后续
关联操作(与SQL相同,不做详细介绍):
INNER JOIN LEFT OUTER JOIN RIGHT OUTER JOIN FULL OUTER JOIN CROSS JOIN (没有限制条件的 INNER JOIN ) LEFT SEMIJOIN (Is more like a filter than a join. It is the syntactical way of expressing) RIGHT SEMIJOIN
预处理参数:
#DECLARE str1 string = "Hello World"; #DECLARE str2 string = "BEGIN" + @str1 + "END"; #}END", @str1); #");
脚本参数:
@@foo@@
类型转换:部分类型可以相互转换
rs1 = SELECT Market, ((double) DwellTime) AS DwellTimeDouble FROM searchlog;
调用 C# 方法:MyHelper.SecondsToMinutes() 是c#语言定义的方法
rs1 = SELECT Market, MyHelper.SecondsToMinutes(DwellTime) AS DwellTimeInMinutes FROM searchlog;
三目运算:
cond ? a : b IF (<cond>, <a>, <b> )
非结构化文本流
Scope处理的内容(输入和输出)可以分为结构化文本流和非结构化文本流。其中,结构化文本流(.ss文件)中包含了列名,数据类型等数据(Schema),并且已经确定了各行以及各列的数据结构,你可以把它看作是数据库中的一张表,因此我们一般不会手动修改.ss文件中的内容。而非结构化文本流一般为普通的文本文件,没有明确规定列名以及格式,甚至是每行和每列的分隔符。但是一般情况下,我们更习惯用Tab(\t)作为列分隔,换行(\n)作为行分隔。
非结构化文本流基本概念:
- 不适用SSTREAM;
- 使用 提取器 (Extrator) 提取并转换 行集 (Rowset);
- 使用 输出器(Outputer) 输出 流(Stream);
- 默认的提取器和输出器,以及用户自定义的提取器和输出器
读取非结构化文本流使用 EXTRACT 关键字,需要指定Extractor ,当然你也可以使用默认的Extractor,用法如下:
rs0 = EXTRACT FirstName : string, LastName : string, Age : int FROM "/test_input.txt" USING DefaultTextExtractor() ;
DefaultTextExtractor() 以Tab(\t)作为列分隔符。当然,你也可以自己实现一种Extractor,来读取文本内容:
public class MyExtractor : Extractor { public override IEnumerable<Row> Extract(StreamReader reader, Row outputRow, string[] args) { string line; while ((line = reader.ReadLine()) != null) { var urls = new List<string>(); string[] datas = line.Split('\t'); ].Split(';'); foreach(var item in urlDatas) { if(!string.IsNullOrEmpty(item)) { outputRow[].UnsafeSet(datas[]); outputRow[].UnsafeSet(item); yield return outputRow; } } } } public override Schema Produces(string[] requestedColumns, string[] args) { return new Schema("Name:string,Email:string"); } }
对应的Scope脚本:
input = EXTRACT * FROM @"input\test.txt" USING MyExtractor(); OUTPUT input TO "result.txt";
以及输入输出:
input\test.txt: Jadfine djatr@outlook.com;tojadfine@outlook.com Kinsan kjmint@outlook.com;sun308@outlook.com;kin_sun@hotmail.com result.txt: Jadfine djatr@outlook.com Jadfine tojadfine@outlook.com Kinsan kjmint@outlook.com Kinsan sun308@outlook.com Kinsan kin_sun@hotmail.com
和我们预想的一样,第二列的Emails 以 ;作为分隔符被分隔成了多条记录。还要特别说明一下,我们要使用自己定义的Extractor,需要继承ScopeRuntime.Extractor类,并重写Extract和Product方法。
Extract方法有三个参数:IEnumerable<Row> Extract(StreamReader reader, Row outputRow, string[] args) 。其中StreamReader 读的是 FROM @"input\test.txt" 中的内容。Row是要输出的行,其中包含 Name(string 类型),Email(string 类型)两列。Row的数量,名称是由Product方法定义的。关于如何通过重写Product方法修改,新增,删除列,将在后续介绍。最后一个参数 string[] args 传递的是我们在Scope脚本中调用此方法时传递的参数,如: USING MyExtractor("arg1","arg2");
结构化文本流
后续。。