背景情報 Hadoop 3.0を実行したり、E-MapReduce (EMR) でSpark、Hive、Prestoなどのサービスを使用したりすると、Object Storage Service (OSS) でデータを直接処理できます。 MaxComputeやData Lake Analytics (DLA) などのAlibaba CloudサービスもOSSでサポートされています。
OSSによって提供されるGetObject 操作では、分析とフィルタリングのためにOSSオブジェクトをローカルコンピューターにダウンロードするためのビッグデータプラットフォームが必要です。 その結果、多くのクエリシナリオでは、大量の帯域幅とクライアントリソースが無駄になります。
この問題に対処するには、SelectObject 操作を使用します。 SelectObject操作を使用すると、OSSはビッグデータプラットフォームによって提供される条件と予測を使用してデータを事前にフィルタリングできます。 その結果、有用なデータのみがビッグデータプラットフォームに返されます。 このようにして、クライアントは、より少ない帯域幅リソースを消費し、より少量のデータを処理して、CPU使用率とメモリ使用量を最小限に抑えることができます。 これにより、OSSベースのデータウェアハウジングとデータ分析がビジネス要件により適したものになります。
課金ルール SelectObject 操作を呼び出したときにスキャンされたオブジェクトのサイズに基づいて課金されます。 詳細については、「データ処理料金 」をご参照ください。
サポートされているオブジェクトタイプ ここでは、SelectObject 操作でサポートされるオブジェクトの種類について説明します。
RFC 4180に準拠するCSVオブジェクト (およびTSVオブジェクトなどのCSVに似たオブジェクト) 。 CSVオブジェクトでは、カスタムの行および列の区切り文字と引用文字を指定できます。
エンコードされたJSONオブジェクトをUTF-8します。 SelectObject操作は、DOCUMENTおよびLINES形式のJSONオブジェクトをサポートします。
標準および低頻度アクセス (IA) オブジェクト。 Archive、Cold Archive、およびDeep Cold Archiveオブジェクトは、オブジェクトに対してSelectObject操作が呼び出される前に復元する必要があります。
OSSによって完全に管理され暗号化されているオブジェクト、またはKey Management Service (KMS) によって管理されているカスタマーマスターキー (CMK) を使用して暗号化されているオブジェクト。
サポートしているデータ型 デフォルトでは、OSSのCSVデータはString型です。 CAST 関数を使用して、データ型を変換できます。
次のサンプルSQL文を使用して、1列目と2列目のデータを整数型のデータに変換します。Select * from OSSOBject where cast (_1 as int) > cast (_2 as int)
。
SelectObject 操作を使用すると、WHERE句を使用してデータ型を暗黙的に変換できます。 たとえば、次のSQL文は、1列目と2列目のデータをInteger型のデータに変換します。
選択_1 from ossobjectここで_1 + _2 > 100
CAST関数を使用しない場合、JSONオブジェクトのデータ型は変更されません。 標準のJSONオブジェクトは、Null、Bool、Int64、Double、Stringなどのさまざまなデータ型をサポートできます。
サンプルSQL文 SQL文の例は、CSVおよびJSONオブジェクト用に提供されます。
CSV
シナリオ
SQL文
最初の10行を返します。
select * from ossobject limit 10
1列目と3列目の整数を返します。 第1列の整数値は、第3列の整数値よりも大きい。
select _1, _3 from ossobject where cast(_1 as int) > cast(_3 as int)
最初の列のデータがXで始まるレコードの数を返します。LIKEの後に指定された漢字はUTF-8にエンコードされている必要があります。
select count(*) from ossobject where _1 like 'X%'
2番目の列の時間値が2018-08-09 11:30:25より遅く、3番目の列の値が200より大きいすべてのレコードを返します。
select * from ossobject where _2 > cast('2018-08-09 11:30:25' as timestamp) and _3 > 200
2列目の浮動小数点数の平均値、合計値、最大値、最小値を返します。
ossobjectからAVG(cast(_6 as double)) 、SUM(cast(_6 as double)) 、MAX(cast(_6 as double)) 、MIN(cast(_6 as double)) を選択します。
1列目と3列目のデータで連結された文字列がTomで始まり、Andersonで終わるすべてのレコードを返します。
select * from ossobject where (_1 || _3) like 'Tom%Anderson'
最初の列の値が3で割り切れるすべてのレコードを返します。
select * from ossobject (_1% 3) = 0
最初の列の値が1995と2012の間にあるすべてのレコードを返します。
select * from ossobject where _1 between 1995 and 2012
5番目の列の値がN、M、G、またはLであるすべてのレコードを返します。
select * from ossobject where _5 in ('N', 'M', 'G', 'L')
2列目と3列目の値の積が100と5列目の値の和より大きいレコードをすべて返します。
select * from ossobject where _2 * _3 > _5 + 100
JSON
サンプルJSONオブジェクト:
{
"contacts":[
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 27,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
},
{
"type": "mobile",
"number": "123 456-7890"
}
],
"children": [],
"配偶者": null
}, …… # 他の同様のノードは省略されます。
]}
次の表に、JSONオブジェクトのサンプルSQL文を示します。
シナリオ
SQL文
ageの値が27のレコードをすべて返します。
select * from ossobject.contacts[*] s where s.age = 27
すべての自宅の電話番号を返します。
select s.number from ossobject.contacts[*].phoneNumbers[*] s where s.type = "home"
配偶者の値がnullであるすべてのレコードを返します。
select * from ossobject s where s.spouse is null
childrenの値が0のレコードをすべて返します。
select * from ossobject s where s.children[0] is null
説明 他のメソッドは使用できないため、上記のステートメントを使用して空の配列を指定します。
シナリオ ほとんどの場合、SelectObjectはマルチパートクエリ、JSONオブジェクトのクエリ、およびログオブジェクトの分析に使用されます。
マルチパートクエリを使用したラージオブジェクトのクエリ
SelectObject 操作で提供されるマルチパートクエリ機能は、GetObject 操作で提供されるバイトベースのマルチパートダウンロード機能に似ています。 データは行ごとまたは分割ごとに分割されます。
CSVオブジェクトの列に改行が含まれていない場合は、オブジェクトをバイト単位で分割できます。 オブジェクトのメタを作成する必要がないため、この方法は簡単です。 列に改行が含まれるJSONオブジェクトまたはCSVオブジェクトをクエリする場合は、次の手順を実行します。
CreateSelectObjectMeta操作を呼び出して、オブジェクトの分割の総数を取得します。 スキャン時間を短縮するために、オブジェクトをクエリする前にSelectObject操作を非同期で呼び出すことをお勧めします。
クライアントのリソースに基づいて、適切な同時実行レベル (n) を選択します。 分割の総数を同時実行レベル (n) で割り、各クエリの分割数を取得します。
マルチパートクエリを実行するために、リクエスト本文でパラメーターを設定します。 たとえば、分割範囲を1〜20に設定できます。
結果を組み合わせる。
JSONオブジェクトの照会
JSONオブジェクトをクエリするときは、FROM句でJSONパス範囲を絞り込みます。
サンプルJSONオブジェクト:
{
"contacts":[
{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
},
{
"type": "mobile",
"number": "123 456-7890"
}
]
}
]}
郵便番号が10021で始まるすべての住所を照会するには、次のSQL文を実行します。select s.address.streetAddress from ossobject.contacts[*] s where s.address.postalCode like '10021% '
またはselect s.streetAddress from ossobject.contacts[*].address s.postalCode like '10021%'
。
JSONパスを持つSQLステートメントは、select s.streetAddress from ossobject.contacts[*].address s where s.postalCode like '10021% '
を実行すると、より正確になるため、パフォーマンスが優れています。
JSONオブジェクトで高精度浮動小数点数を処理する
JSONオブジェクトで高精度の浮動小数点数を計算する場合は、ParseJsonNumberAsStringパラメーターをtrueに設定し、CAST関数を使用して解析されたデータをDecimal型に変換することをお勧めします。 たとえば、属性aの値が123456789.123456789の場合、属性aの精度を維持するために、select s.a from ossobject s where cast(s.a as decimal) > 123456789.12345
ステートメントを実行できます。
手順 OSSコンソールの使用
重要 OSSコンソールでは、最大128 MBのサイズのオブジェクトから最大40 MBのデータを選択して取得できます。
OSSコンソール にログインします。
左側のナビゲーションウィンドウで、バケットリスト をクリックします。 [バケット] ページで、目的のバケットを見つけてクリックします。
左側のナビゲーションツリーで、ファイル > オブジェクト を選択します。
ターゲットオブジェクトの右側で、[操作] 列の を選択します。
[コンテンツの選択] パネルで、パラメーターを設定します。 次の表にパラメーターを示します。
パラメーター
説明
オブジェクトタイプ
有効な値: CSVおよびJSON。
区切り文字
このパラメーターは、オブジェクトタイプがCSVに設定されている場合にのみ使用できます。 有効な値: 、およびCustom。
タイトル行
このパラメーターは、オブジェクトタイプがCSVに設定されている場合にのみ使用できます。 オブジェクトの最初の行に列タイトルが含まれるかどうかを指定します。
JSON表示モード
このパラメーターは、オブジェクトタイプがJSONに設定されている場合にのみ使用できます。 有効な値: JSON_LINESおよびJSON_DOCUMENT
圧縮フォーマット
オブジェクトを圧縮するかどうかを選択します。 GZIP圧縮のみがサポートされています。
[プレビュー] をクリックします。 選択したデータをプレビューします。
重要 標準オブジェクトの選択したデータをプレビューすると、SelectObject操作によって発生したデータスキャン料金が課金されます。 IA、アーカイブ、コールドアーカイブ、またはDeep Cold Archiveオブジェクトの選択されたデータをプレビューすると、SelectObject操作によって発生したデータスキャン料金とデータ取得料金が課金されます。 詳細については、「データ処理料金 」をご参照ください。
[次へ] をクリックします。 SQL文を入力して実行します。
たとえば、People という名前のCSVオブジェクトには、Name 、Company 、およびAge の列が含まれます。
50歳以上で名前がLoraで始まる人を照会するには、次のSQL文を実行します。 ステートメントでは、_1、_2、および_3に列インデックスを指定します。 _1は、最初の列のインデックスを指定します。 _2は、2番目の列のインデックスを指定します。 _3は、3番目の列のインデックスを指定します。
select * from ossobject where _1 like 'Lora * 'and _3 > 50
オブジェクトの行数、最大年齢、および最小年齢を照会するには、次のSQL文を実行します。
select count(*), max(cast(_3 as int)), min(cast(_3 as int)) from oss_object
実行結果を表示します。
[ダウンロード] をクリックして、選択したコンテンツをローカルコンピューターにダウンロードすることもできます。
OSS SDKの使用 オブジェクトのクエリに使用できるのは、OSS SDK for JavaとOSS SDK for Pythonのみです。
Java com.aliyun.oss.mo delをインポートします。*;
com.aliyun.oss.OSSをインポートします。impor t com.aliyun.oss.com mon.auth.*;
com.aliyun.oss.OSSClientBuilderをインポートします。java.io.BufferedReaderをインポートします。java.io.ByteArrayInputStreamをインポートします。java.io.InputStreamReaderをインポートします。/**
* 選択オブジェクトメタデータと選択オブジェクトの作成例。
*
* /
public class SelectObjectSample {
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。
プライベート静的文字列エンドポイント="https://oss-cn-hangzhou.aliyuncs.com";
// バケットの名前を指定します。 例: examplebucket.
プライベート静的文字列bucketName = "examplebucket";
public static void main(String[] args) throws Exception {
// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Create an OSSClient instance.
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
// クエリするオブジェクトの完全パスを指定し、SELECTステートメントを使用してオブジェクトのデータをクエリします。 バケット名をフルパスに含めないでください。
// CSVオブジェクトのフルパスを指定します。
selectCsvSample("test.csv" 、ossClient);
// JSONオブジェクトのフルパスを指定します。
selectJsonSample("test.json" 、ossClient);
ossClient.shutdown();
}
private static void selectCsvSample (文字列キー、OSS ossClient) が例外をスロー {
// アップロードするオブジェクトのコンテンツを指定します。
String content = "name,school,company,age\r\n" +
"Lora Francis,School A,Staples Inc,27\r\n" +
"エレノア・リトル、スクールB、\" Conectiv、Inc\"、43\r\n" +
「ロージー・ヒューズ、スクールC、Western Gas Resources Inc、44\r\n」 +
「ローレンス・ロス、スクールD、メットライフ社、24」;
ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));
SelectObjectMetadata selectObjectMetadata = ossClient.createSelectObjectMetadata ()
new CreateSelectObjectMetadataRequest(bucketName, key)
.withInputSerialization(
new InputSerialization().withCsvInputFormat(
// コンテンツ内のさまざまなレコードを区切るために使用される区切り文字を指定します。 例: \r\n。
新しいCSVFormat().withHeaderInfo(CSVFormat.Header.Use).withRecordDelimiter("\r\n")));
System.out.println(selectObjectMetadata.getCsvObjectMetadata().getTotalLines());
System.out.println(selectObjectMetadata.getCsvObjectMetadata().getSplits());
SelectObjectRequest selectObjectRequest =
新しいSelectObjectRequest(bucketName, key)
.withInputSerialization(
new InputSerialization().withCsvInputFormat(
新しいCSVFormat().withHeaderInfo(CSVFormat.Header.Use).withRecordDelimiter("\r\n")))
. withOutputSerialization(new OutputSerialization().withCsvOutputFormat(new CSVFormat()));
// SELECTステートメントを使用して、4番目の列の値が40より大きいすべてのレコードを照会します。
selectObjectRequest.setExpression("select * from ossobject where _4 > 40");
OSSObject ossObject = ossClient.selectObject(selectObjectRequest);
// オブジェクトの内容を読み取ります。
BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
一方、(TRUE){
String line = reader.readLine();
if (line == null) {
break;
}
System.out.println (ライン);
}
reader.close();
ossClient.de leteObject(bucketName、key);
}
private static void selectJsonSample (文字列キー、OSS ossClient) が例外をスロー {
// アップロードするオブジェクトのコンテンツを指定します。
final String content = "{\n" +
"\t\" name\": \" Lora Francis\",\n" +
"\t\" age\": 27,\n" +
"\t\" company\": \" ステープルズ株式会社 \"\n" +
"}\n" +
"{\n" +
"\t\" name\": \" Eleanor Little\",\n" +
"\t\" age\": 43,\n" +
"\t\" company\": \" Conectiv、Inc\"\n" +
"}\n" +
"{\n" +
"\t\" name\": \" Rosie Hughes\",\n" +
"\t\" age\": 44,\n" +
"\t\" company\": \" Western Gas Resources Inc\"\n" +
"}\n" +
"{\n" +
"\t\" name\": \" ローレンス・ロス \",\n" +
"\t\" age\": 24,\n" +
"\t\" 会社 \": \" メットライフ株式会社 \"\n" +
"}";
ossClient.putObject(bucketName, key, new ByteArrayInputStream(content.getBytes()));
SelectObjectRequest selectObjectRequest =
新しいSelectObjectRequest(bucketName, key)
. withInputSerialization(new InputSerialization())
. withCompressionType(CompressionType.NONE)
. withJsonInputFormat(new JsonFormat().withJsonType(JsonType.LINES)))
. withOutputSerialization(new OutputSerialization())
. withCrcEnabled(true)
. withJsonOutputFormat (新しいJsonFormat())
. withExpression("select * from ossobject as s where s.age > 40"); // SELECTステートメントを使用して、オブジェクト内のデータを照会します。
OSSObject ossObject = ossClient.selectObject(selectObjectRequest);
// オブジェクトの内容を読み取ります。
BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
一方、(TRUE){
String line = reader.readLine();
if (line == null) {
break;
}
System.out.println (ライン);
}
reader.close();
ossClient.de leteObject(bucketName、key);
}
}
Python インポートoss2
oss2.credentialsからEnvironmentVariableCredentialsProviderをインポート
def select_call_back(consumed_bytes, total_bytes=なし):
print('Consumed Bytes:'+ str(consumed_bytes) +'\n')
# 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。
# バケットの名前を指定します。
bucket = oss2.Bucket(auth, 'https:// oss-cn-hangzhou.aliyuncs.com ', 'examplebucket')
key = 'python_select.csv'
content = 'トム・ハンクス、米国、45\r\n' * 1024
filename = 'python_select.csv'
# CSVファイルをアップロードします。
bucket.put_object (キー、コンテンツ)
# SelectObject操作のパラメーターを設定します。
csv_meta_params = {'RecordDelimiter': '\r\n'}
select_csv_params = {'CsvHeaderInfo ': 'None' 、
'RecordDelimiter': '\r\n',
'LineRange' :( 500、1000)}
csv_header = bucket.create_select_object_meta(key, csv_meta_params)
プリント (csv_header.rows)
print(csv_header.splits)
result = bucket.select_object(key, "select * from ossobject where _3 > 44", select_call_back, select_csv_params)
select_content = result.read()
印刷 (select_content)
result = bucket.select_object_to_file (キー、ファイル名、
"select * from ossobject where _3 > 44", select_call_back, select_csv_params)
bucket.de lete_object (キー)
### JSONドキュメント
key = 'python_select.json'
content = "{\" contacts\":[{\" key1\":1,\" key2\":\" hello world1\"},{\" key1\":2,\" key2\":\" hello world2\"}]}"
filename = 'python_select.json'
# JSON DOCUMENTオブジェクトをアップロードします。
bucket.put_object (キー、コンテンツ)
select_json_params = {'Json_Type': 'DOCUMENT'}
result = bucket.select_object(key, "select s.key2 from ossobject.contacts[*] s where s.key1 = 1", None, select_json_params)
select_content = result.read()
印刷 (select_content)
result = bucket.select_object_to_file (キー、ファイル名、
"select s.key2 from ossobject.contacts[*] s where s.key1 = 1", None, select_json_params)
bucket.de lete_object (キー)
### JSONリンク
key = 'python_select_lines.json'
content = "{\" key1\":1,\" key2\":\" hello world1\"}\n{\" key1\":2,\" key2\":\" hello world2\"}"
filename = 'python_select.json'
# JSON LINESオブジェクトをアップロードします。
bucket.put_object (キー、コンテンツ)
select_json_params = {'Json_Type': 'LINES'}
json_header = bucket.create_select_object_meta(key,select_json_params)
プリント (json_header.rows)
print(json_header.splits)
result = bucket.select_object(key, "select s.key2 from ossobject s where s.key1 = 1", None, select_json_params)
select_content = result.read()
印刷 (select_content)
result = bucket.select_object_to_file (キー、ファイル名、
"select s.key2 from ossobject s where s.key1 = 1", None, select_json_params)
bucket.de lete_object(key)
Go パッケージメイン
import (import (import)
"fmt"
「github.com/aliyun/aliyun-oss-go-sdk/oss」
"io/ioutil"
"os"
)
func main() {
// 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// OSSClientインスタンスを作成します。
// バケットが配置されているリージョンのエンドポイントを指定します。 たとえば、バケットが中国 (杭州) リージョンにある場合、エンドポイントをhttps://oss-cn-hangzhou.aliyuncs.comに設定します。 実際のエンドポイントを指定します。
client, err := oss.New("yourEndpoint", ", " ", ", oss.SetCredentialsProvider(&provider))
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// バケットの名前を指定します。 例: examplebucket.
bucket, err := client.Bucket("examplebucket")
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 例: exampledir/exampledata.csv.
キー:= "exampledir/exampledata.csv"
// ローカルCSVファイルのフルパスを指定します。 例: D :\\ localpath\\exampledata.csv。
localCsvFile := "D :\\ localpath\\exampledata.csv"
err = bucket.PutObjectFromFile (キー、localCsvFile)
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
selReq := oss.SelectRequest{}
// SELECTステートメントを実行して、オブジェクト内のデータを照会します。
selReq.Expression = 'select * from ossobject'
body, err := bucket.SelectObject(key, selReq)
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// オブジェクトの内容を読み取ります。
fc, err := ioutil.ReadAll(body)
if err! =nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
defer body.Close()
fmt.Println (文字列 (fc))
}
OSS APIの使用 ビジネスで高度なカスタマイズが必要な場合は、RESTful APIを直接呼び出すことができます。 APIを直接呼び出すには、コードに署名計算を含める必要があります。 詳細は、「SelectObject 」をご参照ください。