S3 从对象中选择内容

选择对象内容 API 通过结构化查询语言 (SQL) 过滤对象内容。

有关清单对象中应包含哪些内容的说明示例,请参阅 AWS Systems Manager 用户指南中清单收集的元数据部分。 在请求中,必须将数据序列化格式指定为对象的逗号分隔值 (CSV) ,以检索指定的内容。 Amazon Web Services (AWS) 命令行界面 (CLI) 选择对象内容使用 CSV 格式将对象数据解析为记录,并仅返回查询中指定的记录。

注: 必须指定响应的数据序列化格式。 您必须具有此操作的 s3:GetObject 许可权。

语法

POST /BUCKET/KEY?select&select-type=2 HTTP/1.1\r\n

示例

POST /testbucket/sample1csv?select&select-type=2 HTTP/1.1\r\n

Bucket

描述

要从中选择对象内容的存储区。

类型

字符串

必需

Key

描述

对象键。

长度约束

1 的最小长度。

类型

字符串

必需

SelectObjectContentRequest

描述

选择对象内容请求参数的根级别标记。

类型

字符串

必需

Expression

描述

用于查询对象的表达式。

类型

字符串

必需

ExpressionType

描述

为示例 SQL 提供的表达式的类型。

类型

字符串

有效值

SQL

必需

InputSerialization

描述

描述正在查询的对象中数据的格式。

类型

字符串

必需

OutputSerialization

描述

以逗号分隔符和换行符返回的数据的格式。

类型

字符串

必需

响应实体

如果操作成功,那么服务会发送回 HTTP 200 响应。 服务以 XML 格式返回数据:

Payload

描述

有效内容参数的根级别标记。

类型

字符串

必需

Records

描述

记录事件。

类型

Base64-encoded 二进制数据对象

必需

False

Stats

描述

统计信息事件。

类型

长整型

必需

False

Ceph Object Gateway 支持以下响应:

示例

{:event-type,records} {:content-type,application/octet-stream} {:message-type,event}

语法 (针对 CSV)

aws --endpoint-URL http://localhost:80 s3api select-object-content
 --bucket BUCKET NAME
 --expression-type SQL
 --input-serialization
 {"CSV": {"FieldDelimiter": "," , "QuoteCharacter": "\"" , "RecordDelimiter" : "\n" , "QuoteEscapeCharacter" : "\\" , "FileHeaderInfo": "USE" }, "CompressionType": "NONE"}
 --output-serialization {"CSV": {}}
 --key OBJECT_NAME.csv
 --expression "select count(0) from s3object where int(_1)<10;" output.csv
注意: --key OBJECT_NAME 中的对象名称不需要 IBM Storage Ceph 7 及更高版本中的 .csv.json.parquet

示例 (对于 CSV)

aws --endpoint-url http://localhost:80 s3api select-object-content
 --bucket testbucket
 --expression-type 'SQL'
 --input-serialization
 '{"CSV": {"FieldDelimiter": "," , "QuoteCharacter": "\"" , "RecordDelimiter" : "\n" , "QuoteEscapeCharacter" : "\\" , "FileHeaderInfo": "USE" }, "CompressionType": "NONE"}'
 --output-serialization '{"CSV": {}}'
 --key testobject.csv
 --expression "select count(0) from s3object where int(_1)<10;" output.csv
语法 (针对 Parquet)
aws --endpoint-url http://localhost:80 s3api select-object-content
 --bucket BUCKET NAME
 --expression-type 'SQL'
 --input-serialization
 '{"Parquet": {}, {"CompressionType": "NONE"}'
 --output-serialization '{"CSV": {}}}'
 --key OBJECT_NAME.parquet
 --expression "select count(0) from s3object where int(_1)<10;" output.csv
注: 唯一受支持的输出序列化为 .csv
示例 (对于 Parquet)
aws --endpoint-url http://localhost:80 s3api select-object-content
 --bucket testbucket
 --expression-type 'SQL'
 --input-serialization
 '{"Parquet":{}, "CompressionType": "NONE"}'
 --output-serialization '{"CSV": {}}}'
 --key testobject.parquet
 --expression "select count(0) from s3object where int(_1)<10;" output.csv
语法 (针对 JSON)
aws --endpoint-url http://localhost:80 s3api select-object-content
 --bucket BUCKET_NAME
 --key OBJECT_NAME.json
 --expression-type 'SQL'
 --input-serialization
 '{"JSON": {"Type": "DOCUMENT"}, "CompressionType": "NONE"}'
 --output-serialization '{"CSV": {}}'
 --expression "select count(*) from S3Object[*];" /dev/stdout
示例 (对于 JSON)
aws s3api --endpoint-url http://localhost:80
select-object-content --bucket test
--key testobject.json
--expression-type 'SQL'
--input-serialization
'{"JSON": {"Type": "DOCUMENT"}, "CompressionType": "NONE"}'
--output-serialization '{"CSV": {}}'
--expression "select count(*) from S3Object[*];" /dev/stdout

示例 (对于 BOTO3)

import pprint
import boto3
from botocore.exceptions import ClientError

def run_s3select(bucket,key,query,column_delim=",",row_delim="\n",quot_char='"',esc_char='\\',csv_header_info="NONE"):

   s3 = boto3.client('s3',
       endpoint_url=endpoint,
       aws_access_key_id=access_key,
       region_name=region_name,
       aws_secret_access_key=secret_key)

   result = ""
   try:
       r = s3.select_object_content(
       Bucket=bucket,
       Key=key,
       ExpressionType='SQL',
       InputSerialization = {"CSV": {"RecordDelimiter" : row_delim, "FieldDelimiter" : column_delim,"QuoteEscapeCharacter": esc_char, "QuoteCharacter": quot_char, "FileHeaderInfo": csv_header_info}, "CompressionType": "NONE"},
       OutputSerialization = {"CSV": {}},
       Expression=query,
       RequestProgress = {"Enabled": progress})

   except ClientError as c:
       result += str(c)
       return result

   for event in r['Payload']:
           if 'Records' in event:
               result = ""
               records = event['Records']['Payload'].decode('utf-8')
               result += records
           if 'Progress' in event:
               print("progress")
               pprint.pprint(event['Progress'],width=1)
           if 'Stats' in event:
               print("Stats")
               pprint.pprint(event['Stats'],width=1)
           if 'End' in event:
               print("End")
               pprint.pprint(event['End'],width=1)

   return result




 run_s3select(
 "my_bucket",
 "my_csv_object",
 "select int(_1) as a1, int(_2) as a2 , (a1+a2) as a3 from s3object where a3>100 and a3<300;")

受支持的功能部件

目前,只支持 AWS s3 select 命令的一部分。 有关支持功能的完整列表,请参见表 1

表 1. AWS s3 选择命令支持的功能
功能部件 详细信息 描述 示例

算术运算符

^ * % / + - ( )

从 s3object; 中选择 (int (_ 1) + int (_ 2)) * int (_ 9)

算术运算符

模百分比

从 s3object 中选择计数 (*) ,其中 cast (_1 as int) %2 = 0;

算术运算符

^ 次幂

从 s3object; 中选择强制类型转换 (2 ^ 10 作为 int)

比较运算符

> < >= <= = !=

从 s3object 中选择 _1 , _2 ,其中 (int (_ 1) + int (_ 3)) >int (_ 5);

逻辑运算符

AND 或 NOT

select count(*) from s3object where not (int(1)>123 and int(_5)<200);

逻辑运算符

为空

针对表达式中的空指示返回 true/false

逻辑运算符和 NULL

不为空

针对表达式中的空指示返回 true/false

逻辑运算符和 NULL

未知状态

查看空句柄并观察具有 NULL 的逻辑操作的结果。 查询将返回 0

select count(*) from s3object where null and (3>2);

具有 NULL 的算术运算符

未知状态

查看空句柄并观察具有 NULL 的二进制操作的结果。 查询将返回 0

select count(*) from s3object where (null+1) and (3>2);

与 NULL 比较

未知状态

查看 null 句柄并观察具有 NULL 的比较操作的结果。 查询将返回 0

select count(*) from s3object where (null*1.5) != 3;

缺少列

未知状态

select count(*) from s3object where _1 is null;

投影列

类似于 if 或 then 或 else

select case when (1+1=(2+1)*3) then ‘case_1’ when ((4*3)=(12)) then ‘case_2’ else ‘case_else’ end, age*2 from s3object;

投影列

类似于 switch/case 缺省值

select case cast(_1 as int) + 1 when 2 then “a” when 3 then “b” else “c” end from s3object;

逻辑运算符

coalesce 返回第一个非空参数

select coalesce(nullif(5,5),nullif(1,1.0),age+12) from s3object;

逻辑运算符

如果两个自变量都相等,那么 nullif 返回 null ,否则返回第一个自变量,nullif(1,1)=NULL nullif(null,1)=NULL nullif(2,1)=2

select nullif(cast(_1 as int),cast(_2 as int)) from s3object;

逻辑运算符

{expression} in ( .. {expression} ..)

select count(*) from s3object where ‘ben’ in (trim(_5),substring(_1,char_length(_1)-3,3),last_name);

逻辑运算符

{expression} between {expression} and {expression}

select _1 from s3object where cast(_1 as int) between 800 and 900;
select count(*) from stdin where substring(_3,char_length(_3),1) between “x” and trim(_1) and substring(_3,char_length(_3)-1,1) = “:”;

逻辑运算符

{expression} like {match-pattern}

select count(*) from s3object where first_name like ‘%de_’; select count(*) from s3object where _1 like "%a[r-s]";

逻辑运算符

{expression} like {match-pattern} escape {char} select count(*) from s3object where “jok_ai” like “%#_ai” escape “#”;

强制类型转换运算符

select cast(123 as int)%2 from s3object;

强制类型转换运算符

select cast(123.456 as float)%2 from s3object;

强制类型转换运算符

select cast(‘ABC0-9’ as string),cast(substr(‘ab12cd’,3,2) as int)*4 from s3object;

强制类型转换运算符

select cast(substring(‘publish on 2007-01-01’,12,10) as timestamp) from s3object;

非 AWS 强制类型转换操作程序

select int(_1),int( 1.2 + 3.4) from s3object;

非 AWS 强制类型转换操作程序

select float(1.2) from s3object;

非 AWS 强制类型转换操作程序

select to_timestamp('1999-10-10T12:23:44Z') from s3object;

汇总函数

总和

select sum(int(_1)) from s3object;

汇总函数

平均值

select avg(cast(_1 as float) + cast(_2 as int)) from s3object;

汇总函数

最小值

select min( int(_1) * int(_5) ) from s3object;

汇总函数

最大值

select max(float(_1)),min(int(_5)) from s3object;

汇总函数

计数

select count(*) from s3object where (int(1)+int(_3))>int(_5);

时间戳记函数

提取

select count(*) from s3object where extract(year from to_timestamp(_2)) > 1950 and extract(year from to_timestamp(_1)) < 1960;

时间戳记函数

日期添加

select count(0) from s3object where date_diff(year,to_timestamp(_1),date_add(day,366,to_timestamp(_1))) = 1;

时间戳记函数

达迪夫

select count(0) from s3object where date_diff(month,to_timestamp(_1),to_timestamp(_2)) = 2;

时间戳记函数

乌特克努

select count(0) from s3object where date_diff(hour,utcnow(),date_add(day,1,utcnow())) = 24

时间戳记函数

to_string

select to_string( to_timestamp(“2009-09-17T17:56:06.234567Z”), “yyyyMMdd-H:m:s”) from s3object;

字符串函数

子串

select count(0) from s3object where int(substring(_1,1,4))>1950 and int(substring(_1,1,4))<1960;

具有 from 负数的子串被视为第一个有效 select substring(“123456789” from -4) from s3object;
具有 from zero for out-of-bound number 的子串就像第一个,最后一个一样有效。 select substring(“123456789” from 0 for 100) from s3object;

字符串函数

修剪

select trim(‘ foobar ‘) from s3object;

字符串函数

修剪

select trim(trailing from ‘ foobar ‘) from s3object;

字符串函数

修剪

select trim(leading from ‘ foobar ‘) from s3object;

字符串函数

修剪

select trim(both ‘12’ from ‘1112211foobar22211122’) from s3object;

字符串函数

下或上

select lower(‘ABcD12#$e’) from s3object;

字符串函数

char_length 和 character_length

select count(*) from s3object where char_length(_3)=3;

复杂查询

select sum(cast(_1 as int)),max(cast(_3 as int)), substring(‘abcdefghijklm’, (2-1)*3+sum(cast(_1 as int))/sum(cast(_1 as int))+1, (count() + count(0))/count(0)) from s3object;

别名支持

select int(_1) as a1, int(_2) as a2 , (a1+a2) as a3 from s3object where a3>100 and a3<300;