全部產品
Search
文件中心

Object Storage Service:使用標量檢索基於中繼資料屬性查詢OSS中的檔案

更新時間:Sep 23, 2025

標量檢索是OSS提供的基於Object中繼資料的索引功能,允許您自訂條件,快速篩選並擷取Object列表。可以協助您更好地管理與瞭解資料結構,方便您後續查詢、統計和管理Object。

使用情境

資料審計情境

通過標量檢索,您可以快速定位檔案,以滿足資料審計或監管需求。例如,在金融服務行業,您可以通過自訂標籤、存取權限等中繼資料進行篩選,從而找到具有特定敏感性層級或特定許可權的檔案,以提升資料審計的效率。

企業備份與歸檔情境

企業在進行資料備份和歸檔時,可以利用標量檢索,例如根據檔案的建立時間、儲存類型或自訂標籤等中繼資料,迅速檢索到特定日期或類型的檔案,從而快速恢複歷史資料或歸檔記錄。

使用限制

  • 地區限制

    華東1(杭州)、華東2(上海)、華北1(青島)、華北2(北京)、華北3(張家口)、華南1(深圳)、華南3(廣州)、西南1(成都)、華北6(烏蘭察布)、中國香港、新加坡、印尼(雅加達)、德國(法蘭克福)、美國(維吉尼亞)、美國(矽谷)、英國(倫敦)地區的Bucket支援使用標量檢索功能。

  • Bucket限制

    開通標量檢索的 Bucket,其包含的檔案數量最多為500億。Bucket內檔案數量超過500億時,可能出現檢索效能下降的情況。如需處理更大規模的資料,請聯絡支援人員進行評估。

  • 分區上傳

    對於通過分區上傳產生的Object,查詢結果中只顯示已通過CompleteMultipartUpload操作將片段(Part)合成的完整Object,不顯示已初始化但未完成(Complete)或者未中止(Abort)的片段。

效能參考

OSS 標量檢索模式的效能表現如下內容,僅供參考。

  • 存量檔案索引產生時間參考

    • 單 Bucket 檔案數量 1 億:4 小時

    • 單 Bucket 檔案數量 10 億:10 小時左右

    • 單 Bucket 檔案數量 100 億:1~3 天左右

    • 單 Bucket 檔案數量 200 億:2~4 天左右

    • 單 Bucket 檔案數量 300 億:3~6 天左右

    • 單 Bucket 檔案數量 500 億:6~10 天左右

    • 若您的 bucket 內檔案數量超出 10 億,且檔案攜帶 Tag,則索引產生的時間會較上述時間更長。

  • 增量檔案索引更新時間參考

    OSS 預設為標量檢索模式額外提供 5000 QPS(即每秒可處理5000個檔案索引更新要求),該QPS不佔用您 Bucket 的 QoS。當 Bucket 內新增、修改或刪除的QPS低於預設值5000時,檔案從上傳或修改到可被檢索的延遲通常在分鐘級;若超過預設值5000QPS,您可以通過支援人員聯絡我們,我們將根據實際情況評估,並提供支援人員。

  • 檔案檢索響應效能

    檢索結果返回為秒級,預設逾時時間為 30 秒。

開啟標量檢索

使用OSS控制台

Bucket為華東1(杭州)、華東2(上海)、華北1(青島)、華北2(北京)、華北3(張家口)、華南1(深圳)、華南3(廣州)、西南1(成都)、中國香港、新加坡、印尼(雅加達)、德國(法蘭克福)

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列, 選擇文件管理 > 數據索引

  4. 資料索引頁面,首次使用資料索引功能時,需要按指引完成對 AliyunMetaQueryDefaultRole 角色的授權,以便 OSS 服務能管理 Bucket 中的資料。授權後,單擊開通資料索引

  5. 選擇標量檢索,單擊確認開啟

    說明

    開啟標量檢索需要等待一定的時間,具體等待時間長度取決於Bucket中Object的數量。

Bucket為英國(倫敦)、華北6(烏蘭察布)、美國(維吉尼亞)、美國(矽谷)地區

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列, 選擇文件管理 > 數據索引首次使用資料索引功能時,需要按指引完成對 AliyunMetaQueryDefaultRole 角色的授權,以便 OSS 服務能管理 Bucket 中的資料。

  4. 開啟中繼資料管理

    說明

    開啟中繼資料管理需要等待一定的時間,具體等待時間長度取決於Bucket中Object的數量。

使用阿里雲SDK

使用標量檢索功能前,您需要為指定Bucket開啟中繼資料管理功能,樣本如下。

Java

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.MetaQueryMode;

public class OpenMetaQuery {
    public static void main(String[] args) throws com.aliyuncs.exceptions.ClientException {
        // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
        String region = "cn-hangzhou";

        // 建立OSSClient執行個體。
        //當OSSClient執行個體不再使用時,調用shutdown方法以釋放資源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // 開啟標量檢索功能。
            ossClient.openMetaQuery(bucketName);
        } catch (OSSException oe) {
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Error Message: " + ce.getMessage());
        } finally {
            // 關閉OSSClient。
            if(ossClient != null){
                ossClient.shutdown();
            }
        }
    }
}

Python

import argparse
import alibabacloud_oss_v2 as oss

# 建立命令列參數解析器,並添加描述資訊
parser = argparse.ArgumentParser(description="open meta query sample")
# 添加必需的命令列參數 --region,用於指定儲存空間所在的地區
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加必需的命令列參數 --bucket,用於指定要操作的儲存空間名稱
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加可選的命令列參數 --endpoint,用於指定訪問OSS時使用的網域名稱
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')

def main():
    # 解析命令列參數
    args = parser.parse_args()

    # 從環境變數中載入認證資訊
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK提供的預設配置
    cfg = oss.config.load_default()
    # 設定認證資訊提供者
    cfg.credentials_provider = credentials_provider
    # 根據命令列參數設定地區
    cfg.region = args.region
    # 如果提供了endpoint,則更新配置中的endpoint
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 建立OSS用戶端
    client = oss.Client(cfg)

    # 發起開啟元查詢請求
    result = client.open_meta_query(oss.OpenMetaQueryRequest(
            bucket=args.bucket,
    ))

    # 列印請求的結果狀態代碼和請求ID
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          )

# 當作為主程式運行時調用main函數
if __name__ == "__main__":
    main()

Go

package main

import (
	"context"
	"flag"   
	"log"     

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"          
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" 
)

var (
	region     string // 定義一個變數來儲存從命令列擷取的地區(Region)資訊
	bucketName string // 定義一個變數來儲存從命令列擷取的儲存空間名稱
)

// init函數在main函數之前執行,用來初始化程式
func init() {
	// 設定命令列參數來指定region
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	// 設定命令列參數來指定bucket名稱
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}

func main() {
	flag.Parse() // 解析命令列參數

	// 檢查是否提供了儲存空間名稱,如果沒有提供,則輸出預設參數並退出程式
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required") // 記錄錯誤並終止程式
	}

	// 檢查是否提供了地區資訊,如果沒有提供,則輸出預設參數並退出程式
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required") // 記錄錯誤並終止程式
	}

	// 建立用戶端配置,並使用環境變數作為憑證提供者
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := oss.NewClient(cfg) // 使用配置建立一個新的OSS用戶端執行個體

	// 構建一個OpenMetaQuery請求,用於開啟特定儲存空間的中繼資料管理功能
	request := &oss.OpenMetaQueryRequest{
		Bucket: oss.Ptr(bucketName), // 指定要操作的儲存空間名稱
	}
	result, err := client.OpenMetaQuery(context.TODO(), request) // 執行請求以開啟儲存空間的中繼資料管理功能
	if err != nil {
		log.Fatalf("failed to open meta query %v", err) // 如果有錯誤發生,記錄錯誤資訊並終止程式
	}

	log.Printf("open meta query result:%#v\n", result) // 列印開啟中繼資料管理的結果
}

PHP

<?php

// 引入自動負載檔案,確保依賴庫能夠正確載入
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定義命令列參數的描述資訊
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地區(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 訪問網域名稱(可選)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名稱(必填)
];

// 將參數描述轉換為getopt所需的長選項格式
// 每個參數後面加上":"表示該參數需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// 解析命令列參數
$options = getopt("", $longopts);

// 驗證必填參數是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 擷取參數的協助資訊
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填參數缺失,則退出程式
    }
}

// 從解析的參數中提取值
$region = $options["region"]; // Bucket所在的地區
$bucket = $options["bucket"]; // Bucket名稱

// 載入環境變數中的憑證資訊
// 使用EnvironmentVariableCredentialsProvider從環境變數中讀取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的預設配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 設定憑證提供者
$cfg->setRegion($region); // 設定Bucket所在的地區
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了訪問網域名稱,則設定endpoint
}

// 建立OSS用戶端執行個體
$client = new Oss\Client($cfg);

// 建立OpenMetaQueryRequest對象,用於開啟Bucket的標量檢索功能
$request = new Oss\Models\OpenMetaQueryRequest(
    bucket: $bucket
);

// 執行開啟標量檢索功能的操作
$result = $client->openMetaQuery($request);

// 列印開啟標量檢索功能的結果
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP狀態代碼,例如200表示成功
    'request id:' . $result->requestId . PHP_EOL     // 請求ID,用於調試或追蹤請求
);

使用ossutil

以下樣本展示了如何開啟儲存空間examplebucket的中繼資料管理功能。

ossutil api open-meta-query --bucket examplebucket

關於該命令的更多資訊,請參見open-meta-query

發起標量檢索

使用OSS控制台

以尋找所有檔案大小小於500KB,最後更新時間在2024年9月11日0:00至2024年9月12日0:00的檔案,輸出結果按檔案大小升序排列,並按檔案大小統計最大值為例:

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列, 選擇文件管理 > 數據索引

  4. 按以下說明配置參數,其他參數保留預設設定。

    • 最後修改時間設定為2024年9月11日0:00至2024年9月12日0:00。

    • 檔案大小設定為小於500KB。

  5. 展開更多過濾條件

    • 對象排序方式選擇按照檔案大小升序排列。

    • 資料彙總選擇按照檔案大小最大值彙總輸出。

    image

  6. 單擊查詢。符合檢索條件的所有檔案共2個,如下圖所示,檔案最大為434KB。

    image

    如需瞭解完整的檢索條件和輸出設定,請參見檢索條件及輸出設定

使用阿里雲SDK

通過標量檢索功能查詢滿足指定條件Object,程式碼範例如下。

Java

如需瞭解更多程式碼範例,請參見標量檢索(Java SDK)

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
import java.util.ArrayList;
import java.util.List;

public class DoMetaQuery {
    public static void main(String[] args) throws Exception {
        // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
        String region = "cn-hangzhou";

        // 建立OSSClient執行個體。
        // 當OSSClient執行個體不再使用時,調用shutdown方法以釋放資源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // 查詢滿足指定條件的檔案(Object),並按照指定欄位和排序方式列舉檔案資訊。
            int maxResults = 20;
            // 指定查詢小於1048576位元組的檔案,且最多返回20個結果,返回結果按升序排列。
            String query = "{\"Field\": \"Size\",\"Value\": \"1048576\",\"Operation\": \"lt\"}";
            String sort = "Size";
            DoMetaQueryRequest doMetaQueryRequest = new DoMetaQueryRequest(bucketName, maxResults, query, sort);
            Aggregation aggregationRequest = new Aggregation();
            Aggregations aggregations = new Aggregations();
            List<Aggregation> aggregationList = new ArrayList<Aggregation>();
            // 指定彙總操作的欄位名稱。
            aggregationRequest.setField("Size");
            // 指定彙總操作的操作符,max表示最大值。
            aggregationRequest.setOperation("max");
            aggregationList.add(aggregationRequest);
            aggregations.setAggregation(aggregationList);

            // 設定彙總操作。
            doMetaQueryRequest.setAggregations(aggregations);
            doMetaQueryRequest.setOrder(SortOrder.ASC);
            DoMetaQueryResult doMetaQueryResult = ossClient.doMetaQuery(doMetaQueryRequest);
            if(doMetaQueryResult.getFiles() != null){
                for(ObjectFile file : doMetaQueryResult.getFiles().getFile()){
                    System.out.println("Filename: " + file.getFilename());
                    // 擷取標識Object的內容。
                    System.out.println("ETag: " + file.getETag());
                    // 擷取Object的存取權限
                    System.out.println("ObjectACL: " + file.getObjectACL());
                    // 擷取Object的類型。
                    System.out.println("OssObjectType: " + file.getOssObjectType());
                    // 擷取Object的儲存類型。
                    System.out.println("OssStorageClass: " + file.getOssStorageClass());
                    // 擷取Object的標籤個數。
                    System.out.println("TaggingCount: " + file.getOssTaggingCount());
                    if(file.getOssTagging() != null){
                        for(Tagging tag : file.getOssTagging().getTagging()){
                            System.out.println("Key: " + tag.getKey());
                            System.out.println("Value: " + tag.getValue());
                        }
                    }
                    if(file.getOssUserMeta() != null){
                        for(UserMeta meta : file.getOssUserMeta().getUserMeta()){
                            System.out.println("Key: " + meta.getKey());
                            System.out.println("Value: " + meta.getValue());
                        }
                    }
                }
            } else if(doMetaQueryResult.getAggregations() != null){
                for(Aggregation aggre : doMetaQueryResult.getAggregations().getAggregation()){
                    // 擷取彙總欄位名稱。
                    System.out.println("Field: " + aggre.getField());
                    // 擷取彙總欄位的操作符。
                    System.out.println("Operation: " + aggre.getOperation());
                    // 擷取彙總操作的結果值。
                    System.out.println("Value: " + aggre.getValue());
                    if(aggre.getGroups() != null && aggre.getGroups().getGroup().size() > 0){
                        // 擷取分組彙總的值。
                        System.out.println("Groups value: " + aggre.getGroups().getGroup().get(0).getValue());
                        // 擷取分組彙總的總個數。
                        System.out.println("Groups count: " + aggre.getGroups().getGroup().get(0).getCount());
                    }
                }
            } else {
                System.out.println("NextToken: " + doMetaQueryResult.getNextToken());
            }
        } catch (OSSException oe) {
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Error Message: " + ce.getMessage());
        } finally {
            // 關閉OSSClient。
            ossClient.shutdown();
        }
    }
}

Python

如需瞭解更多程式碼範例,請參見標量檢索

import argparse
import alibabacloud_oss_v2 as oss

# 建立一個命令列參數解析器,用於接收使用者輸入的參數
parser = argparse.ArgumentParser(description="do meta query sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')

def main():
    # 解析命令列參數
    args = parser.parse_args()

    # 從環境變數中載入認證資訊
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK的預設配置
    cfg = oss.config.load_default()
    # 設定認證提供者
    cfg.credentials_provider = credentials_provider
    # 根據傳入參數設定地區
    cfg.region = args.region
    # 如果提供了endpoint,則更新配置中的endpoint
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 建立OSS用戶端
    client = oss.Client(cfg)

    # 執行中繼資料查詢操作
    result = client.do_meta_query(oss.DoMetaQueryRequest(
            bucket=args.bucket,  # 指定要查詢的儲存空間
            meta_query=oss.MetaQuery(  # 定義查詢的具體內容
                aggregations=oss.MetaQueryAggregations(  # 定義彙總操作
                    aggregations=[  # 彙總列表
                        oss.MetaQueryAggregation(  # 第一個彙總:計算總大小
                            field='Size',
                            operation='sum',
                        ),
                        oss.MetaQueryAggregation(  # 第二個彙總:找出最大值
                            field='Size',
                            operation='max',
                        )
                    ],
                ),
                next_token='',  # 分頁標記
                max_results=80369,  # 返回的最大結果數
                query='{"Field": "Size","Value": "1048576","Operation": "gt"}',  # 查詢條件
                sort='Size',  # 排序欄位
                order=oss.MetaQueryOrderType.DESC,  # 排序方式
            ),
    ))

    # 輸出查詢結果的基本資料
    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          # 下面這些注釋掉的部分可以根據需要開啟來擷取更詳細的資訊
          # f' files: {result.files},'
          # f' file: {result.files.file},'
          # f' file modified time: {result.files.file.file_modified_time},'
          # f' etag: {result.files.file.etag},'
          # f' server side encryption: {result.files.file.server_side_encryption},'
          # f' oss tagging count: {result.files.file.oss_tagging_count},'
          # f' oss tagging: {result.files.file.oss_tagging},'
          # f' key: {result.files.file.oss_tagging.taggings[0].key},'
          # f' value: {result.files.file.oss_tagging.taggings[0].value},'
          # f' key: {result.files.file.oss_tagging.taggings[1].key},'
          # f' value: {result.files.file.oss_tagging.taggings[1].value},'
          # f' oss user meta: {result.files.file.oss_user_meta},'
          # f' key: {result.files.file.oss_user_meta.user_metas[0].key},'
          # f' value: {result.files.file.oss_user_meta.user_metas[0].value},'
          # f' key: {result.files.file.oss_user_meta.user_metas[1].key},'
          # f' value: {result.files.file.oss_user_meta.user_metas[1].value},'
          # f' filename: {result.files.file.filename},'
          # f' size: {result.files.file.size},'
          # f' oss object type: {result.files.file.oss_object_type},'
          # f' oss storage class: {result.files.file.oss_storage_class},'
          # f' object acl: {result.files.file.object_acl},'
          # f' oss crc64: {result.files.file.oss_crc64},'
          # f' server side encryption customer algorithm: {result.files.file.server_side_encryption_customer_algorithm},'
          # f' aggregations: {result.aggregations},'
          f' field: {result.aggregations.aggregations[0].field},'
          f' operation: {result.aggregations.aggregations[0].operation},'
          f' field: {result.aggregations.aggregations[1].field},'
          f' operation: {result.aggregations.aggregations[1].operation},'
          f' next token: {result.next_token},'
    )

    # 如果存在檔案資訊,則列印標籤和使用者自訂中繼資料
    if result.files:
        if result.files.file.oss_tagging.taggings:
            for r in result.files.file.oss_tagging.taggings:
                print(f'result: key: {r.key}, value: {r.value}')
        if result.files.file.oss_user_meta.user_metas:
            for r in result.files.file.oss_user_meta.user_metas:
                print(f'result: key: {r.key}, value: {r.value}')
    # 列印所有彙總的結果
    if result.aggregations.aggregations:
        for r in result.aggregations.aggregations:
            print(f'result: field: {r.field}, operation: {r.operation}')

if __name__ == "__main__":
    main()

Go

如需瞭解更多程式碼範例,請參見標量檢索(Go SDK V2)

package main

import (
	"context"
	"flag"
	"fmt"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

var (
	region     string // 定義一個變數來儲存從命令列擷取的地區(Region)資訊
	bucketName string // 定義一個變數來儲存從命令列擷取的儲存空間名稱
)

// init函數在main函數之前執行,用來初始化程式
func init() {
	// 設定命令列參數來指定region,預設為空白字串
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	// 設定命令列參數來指定bucket名稱,預設為空白字串
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}

func main() {
	flag.Parse() // 解析命令列參數

	// 檢查是否提供了儲存空間名稱,如果沒有提供,則輸出預設參數並退出程式
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 檢查是否提供了地區資訊,如果沒有提供,則輸出預設參數並退出程式
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 建立用戶端配置,並使用環境變數作為憑證提供者和指定的地區
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := oss.NewClient(cfg) // 使用配置建立一個新的OSS用戶端執行個體

	// 構建一個DoMetaQuery請求,用於執行中繼資料查詢滿足指定條件Object
	request := &oss.DoMetaQueryRequest{
		Bucket: oss.Ptr(bucketName), // 指定要查詢的儲存空間名稱
		MetaQuery: &oss.MetaQuery{
			Query: oss.Ptr(`{"Field": "Size","Value": "1048576","Operation": "gt"}`), // 查詢條件:大小大於1MB的對象
			Sort:  oss.Ptr("Size"),                                                   // 排序欄位:按對象大小排序
			Order: oss.Ptr(oss.MetaQueryOrderAsc),                                    // 排序次序:升序
		},
	}
	result, err := client.DoMetaQuery(context.TODO(), request) // 發送請求以執行中繼資料查詢
	if err != nil {
		log.Fatalf("failed to do meta query %v", err)
	}

	// 列印NextToken,用於分頁查詢下一頁的資料
	fmt.Printf("NextToken:%s\n", *result.NextToken)

	// 遍曆返回的結果,列印出每個檔案的詳細資料
	for _, file := range result.Files {
		fmt.Printf("File name: %s\n", *file.Filename)
		fmt.Printf("size: %d\n", file.Size)
		fmt.Printf("File Modified Time:%s\n", *file.FileModifiedTime)
		fmt.Printf("Oss Object Type:%s\n", *file.OSSObjectType)
		fmt.Printf("Oss Storage Class:%s\n", *file.OSSStorageClass)
		fmt.Printf("Object ACL:%s\n", *file.ObjectACL)
		fmt.Printf("ETag:%s\n", *file.ETag)
		fmt.Printf("Oss CRC64:%s\n", *file.OSSCRC64)
		if file.OSSTaggingCount != nil {
			fmt.Printf("Oss Tagging Count:%d\n", *file.OSSTaggingCount)
		}

		// 列印對象的標籤資訊
		for _, tagging := range file.OSSTagging {
			fmt.Printf("Oss Tagging Key:%s\n", *tagging.Key)
			fmt.Printf("Oss Tagging Value:%s\n", *tagging.Value)
		}

		// 列印使用者自訂中繼資料資訊
		for _, userMeta := range file.OSSUserMeta {
			fmt.Printf("Oss User Meta Key:%s\n", *userMeta.Key)
			fmt.Printf("Oss User Meta Key Value:%s\n", *userMeta.Value)
		}
	}
}

PHP

如需瞭解更多程式碼範例,請參見標量檢索(PHP SDK V2)

<?php

// 引入自動負載檔案,確保依賴庫能夠正確載入
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定義命令列參數的描述資訊
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地區(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 訪問網域名稱(可選)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名稱(必填)
];

// 將參數描述轉換為getopt所需的長選項格式
// 每個參數後面加上":"表示該參數需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// 解析命令列參數
$options = getopt("", $longopts);

// 驗證必填參數是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 擷取參數的協助資訊
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填參數缺失,則退出程式
    }
}

// 從解析的參數中提取值
$region = $options["region"]; // Bucket所在的地區
$bucket = $options["bucket"]; // Bucket名稱

// 載入環境變數中的憑證資訊
// 使用EnvironmentVariableCredentialsProvider從環境變數中讀取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的預設配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 設定憑證提供者
$cfg->setRegion($region); // 設定Bucket所在的地區
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了訪問網域名稱,則設定endpoint
}

// 建立OSS用戶端執行個體
$client = new Oss\Client($cfg);

// 建立DoMetaQueryRequest對象,用於執行中繼資料查詢操作
$request = new \AlibabaCloud\Oss\V2\Models\DoMetaQueryRequest(
    bucket: $bucket,
    metaQuery: new \AlibabaCloud\Oss\V2\Models\MetaQuery(
        maxResults: 5, // 最大返回結果數量
        query: "{'Field': 'Size','Value': '1048576','Operation': 'gt'}", // 查詢條件:大小大於1MB的對象
        sort: 'Size', // 按照對象大小排序
        order: \AlibabaCloud\Oss\V2\Models\MetaQueryOrderType::ASC, // 升序排序
        aggregations: new \AlibabaCloud\Oss\V2\Models\MetaQueryAggregations( // 彙總操作
            aggregations: [
                new \AlibabaCloud\Oss\V2\Models\MetaQueryAggregation(
                    field: 'Size', // 對象大小欄位
                    operation: 'sum' // 彙總操作:求和
                ),
                new \AlibabaCloud\Oss\V2\Models\MetaQueryAggregation(
                    field: 'Size', // 對象大小欄位
                    operation: 'max' // 彙總操作:求最大值
                ),
            ]
        )
    )
);

// 執行中繼資料查詢操作
$result = $client->doMetaQuery($request);

// 列印中繼資料查詢的結果
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP狀態代碼,例如200表示成功
    'request id:' . $result->requestId . PHP_EOL .   // 請求ID,用於調試或追蹤請求
    'result:' . var_export($result, true) . PHP_EOL  // 查詢結果,包含匹配的對象及其彙總資料
);

使用ossutil

您可以使用命令列工具ossutil通過標量檢索功能查詢滿足指定條件的Object,ossutil的安裝請參見安裝ossutil

以下樣本展示了如何查詢儲存空間examplebucket中滿足指定條件的檔案。

ossutil api do-meta-query --bucket examplebucket --meta-query "{\"MaxResults\":\"5\",\"Query\":\"{\\\"Field\\\": \\\"Size\\\",\\\"Value\\\": \\\"1048576\\\",\\\"Operation\\\": \\\"gt\\\"}\",\"Sort\":\"Size\",\"Order\":\"asc\",\"Aggregations\":{\"Aggregation\":[{\"Field\":\"Size\",\"Operation\":\"sum\"},{\"Field\":\"Size\",\"Operation\":\"max\"}]}}"

關於該命令的更多資訊,請參見do-meta-query

關閉標量檢索

  • 關閉該功能不會影響您 OSS 中已儲存的資料。若後續重新開啟,系統將重新掃描存量檔案並構建索引,需要一定等待時間,具體時間取決於您的檔案數量。

  • 功能關閉後的下一小時會停止計費,但出賬會有一定延遲,請及時關注賬單金額。

使用OSS控制台

登入OSS管理主控台,在資料索引功能頁,單擊中繼資料管理右側關閉,按提示確認關閉即可。

image

使用阿里雲SDK

Java

如需瞭解更多程式碼範例,請參見標量檢索(Java SDK)

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;

public class CloseMetaQuery {
    public static void main(String[] args) throws Exception {
        // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
        String region = "cn-hangzhou";

        // 建立OSSClient執行個體。
        // 當OSSClient執行個體不再使用時,調用shutdown方法以釋放資源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            // 關閉儲存空間(Bucket)的標量檢索功能。
            ossClient.closeMetaQuery(bucketName);
        } catch (OSSException oe) {
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Error Message: " + ce.getMessage());
        } finally {
            // 關閉OSSClient。
            if(ossClient != null){
                ossClient.shutdown();
            }
        }
    }
}

Python

如需瞭解更多程式碼範例,請參見標量檢索

import argparse
import alibabacloud_oss_v2 as oss

# 建立一個ArgumentParser對象,用於處理命令列參數
parser = argparse.ArgumentParser(description="close meta query sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')

def main():
    # 解析命令列參數
    args = parser.parse_args()

    # 從環境變數中載入憑據資訊
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK的預設配置
    cfg = oss.config.load_default()
    # 設定憑據提供者為從環境變數擷取的憑據
    cfg.credentials_provider = credentials_provider
    # 設定配置中的地區資訊
    cfg.region = args.region
    # 如果提供了endpoint,則設定配置中的endpoint
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 建立OSS用戶端
    client = oss.Client(cfg)

    # 調用close_meta_query方法關閉指定儲存空間的中繼資料查詢功能
    result = client.close_meta_query(oss.CloseMetaQueryRequest(
            bucket=args.bucket,
    ))

    # 列印響應的狀態代碼和請求ID
    print(f'status code: {result.status_code}, request id: {result.request_id}')

# 當此指令碼直接運行時執行main函數
if __name__ == "__main__":
    main()

Go

如需瞭解更多程式碼範例,請參見標量檢索(Go SDK V2)

package main

import (
	"context"
	"flag"    
	"log"    

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"          
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" 
)

var (
	region     string // 定義一個變數來儲存從命令列擷取的地區(Region)資訊
	bucketName string // 定義一個變數來儲存從命令列擷取的儲存空間名稱
)

// init函數在main函數之前執行,用來初始化程式
func init() {
	// 設定命令列參數來指定region
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	// 設定命令列參數來指定bucket名稱
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}


func main() {
	flag.Parse() // 解析命令列參數

	// 檢查是否提供了儲存空間名稱,如果沒有提供,則輸出預設參數並退出程式
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required") // 記錄錯誤並終止程式
	}

	// 檢查是否提供了地區資訊,如果沒有提供,則輸出預設參數並退出程式
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required") // 記錄錯誤並終止程式
	}

	// 建立用戶端配置,並使用環境變數作為憑證提供者和指定的地區
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := oss.NewClient(cfg) // 建立一個新的OSS用戶端執行個體

	// 構建一個CloseMetaQuery請求,用於關閉特定儲存空間的中繼資料管理功能
	request := &oss.CloseMetaQueryRequest{
		Bucket: oss.Ptr(bucketName), // 指定要操作的儲存空間名稱
	}
	result, err := client.CloseMetaQuery(context.TODO(), request) // 執行請求以關閉儲存空間的中繼資料管理功能
	if err != nil {
		log.Fatalf("failed to close meta query %v", err) // 如果有錯誤發生,記錄錯誤資訊並終止程式
	}

	log.Printf("close meta query result:%#v\n", result)
}

PHP

如需瞭解更多程式碼範例,請參見標量檢索(PHP SDK V2)

<?php

// 引入自動負載檔案,確保依賴庫能夠正確載入
require_once __DIR__ . '/../vendor/autoload.php';

use AlibabaCloud\Oss\V2 as Oss;

// 定義命令列參數的描述資訊
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地區(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 訪問網域名稱(可選)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名稱(必填)
];

// 將參數描述轉換為getopt所需的長選項格式
// 每個參數後面加上":"表示該參數需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));

// 解析命令列參數
$options = getopt("", $longopts);

// 驗證必填參數是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 擷取參數的協助資訊
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填參數缺失,則退出程式
    }
}

// 從解析的參數中提取值
$region = $options["region"]; // Bucket所在的地區
$bucket = $options["bucket"]; // Bucket名稱

// 載入環境變數中的憑證資訊
// 使用EnvironmentVariableCredentialsProvider從環境變數中讀取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();

// 使用SDK的預設配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 設定憑證提供者
$cfg->setRegion($region); // 設定Bucket所在的地區
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了訪問網域名稱,則設定endpoint
}

// 建立OSS用戶端執行個體
$client = new Oss\Client($cfg);

// 建立CloseMetaQueryRequest對象,用於關閉Bucket的檢索功能
$request = new \AlibabaCloud\Oss\V2\Models\CloseMetaQueryRequest(
    bucket: $bucket
);

// 執行關閉檢索功能的操作
$result = $client->closeMetaQuery($request);

// 列印關閉檢索功能的結果
printf(
    'status code:' . $result->statusCode . PHP_EOL . // HTTP狀態代碼,例如200表示成功
    'request id:' . $result->requestId . PHP_EOL     // 請求ID,用於調試或追蹤請求
);

使用ossutil

以下樣本展示了如何關閉儲存空間examplebucket的中繼資料管理功能。命令樣本如下:

ossutil api close-meta-query --bucket examplebucket

關於該命令的更多資訊,請參見close-meta-query

檢索條件及輸出設定

檢索條件

以下是完整的檢索條件,您可以根據需要進行單獨或組合設定。

OSS中繼資料檢索條件

檢索條件

說明

存儲類型

預設選中OSS支援的標準、低頻訪問、歸檔、冷歸檔和深度冷歸檔多種儲存類型。您可以按需選擇希望在查詢結果中顯示的Object儲存類型。

讀寫權限

預設選中OSS支援的四種讀寫權限ACL,即繼承Bucket、私人、公用讀取以及公用讀寫。您可以按需選擇希望在查詢結果中顯示的Object讀寫權限。

文件名

支援模糊比對等於。如果您希望在查詢結果中顯示某個檔案名稱,例如exampleobject.txt。您可以通過以下兩種方式匹配目標檔案:

  • 選擇等於,然後輸入完整的檔案名稱exampleobject.txt

  • 選擇模糊比對,然後輸入檔案首碼或者尾碼,例如example或者.txt

    重要

    模糊比對可命中Object名稱的任一字元,例如輸入test,則查詢結果中將顯示localfolder/test/.example.jpglocalfolder/test.jpg等。

上傳類型

預設選中OSS支援的四種Object類型,您可以按需選擇希望在查詢結果中顯示的Object類型。Object類型說明如下:

  • Normal:通過簡單上傳方式產生的Object。

  • Multipart:通過分區上傳方式產生的Object。

  • Appendable:通過追加上傳方式產生的Object。

  • Symlink:為快速存取Object建立的軟連結。

最後修改時間

指定Object被最後修改的起始日期結束日期,時間精確到秒。

檔案大小

支援等於大於大於等於小於小於等於五種篩選條件,檔案大小單位為KB。

對象版本

僅支援查詢目前的版本Object。

對象ETag及標籤檢索條件

如需根據對象ETag及標籤進行過濾尋找,可輸入您希望在查詢結果中顯示的Object對應的ETag或標籤資訊。

  • ETag僅支援精確匹配。ETag必須帶引號,樣本值為"5B3C1A2E0563E1B002CC607C6689"。可輸入多個ETag,每行一個。

  • 以索引值對(Key-Value)的形式指定對象標籤。對象標籤的Key和Value均區分大小寫。關於標籤規則的更多資訊,請參見對象標籤

結果輸出設定

您可對輸出結果進行排序和簡單統計。

  • 對象排序方式:支援根據最後修改時間、檔案名稱和檔案大小進行升序、降序及預設排序。您可以按需選擇並排序檢索結果,便於快速找到所需檔案。

  • 資料彙總:支援多種輸出類型,您可以對檢索結果進行去重統計、分組計數、最大值、最小值、平均值和求和等計算,便於高效分析和管理資料。

相關API

以上操作方式底層基於API實現,如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。

關於開啟中繼資料管理功能的更多資訊,請參見OpenMetaQuery

關於查詢滿足指定條件的檔案,請參見DoMetaQuery

關於關閉中繼資料管理功能的更多資訊,請參見CloseMetaQuery

計費說明

  • 標量檢索費用主要來自以下兩個方面:

    • 標量檢索功能計費項目(公測期間免費)

      包括Object的中繼資料管理費用。當前處於公測階段暫不計費,將於 2025 年 8 月 25 日公測結束後正式計費。公測結束後將按OSS資料索引定價標準計費,詳見資料索引費用

    • API請求費用

      在增量檔案索引更新期間會產生API請求費用,按照API調用次數收費。涉及的API請求如下:

      行為

      API

      次數

      為Bucket中的檔案構建索引

      HeadObjectGetObject

      每個檔案調用1次

      Bucket中檔案存在Tag

      GetObjectTag

      每個攜帶Tag的檔案調用1次

      Bucket中檔案攜帶自訂Meta

      GetObjectMeta

      每個攜帶自訂Meta的檔案調用1次

      Bucket中存在軟連結檔案

      GetSymlink

      每個攜帶軟連結的檔案調用1次

      掃描Bucket中的檔案

      ListObjects

      每掃描1000個檔案調用1次

      關於OSS API的請求費用,請參見請求費用

  • 如您希望停止相關計費,請及時關閉標量檢索

常見問題

Bucket內檔案數量達到上億層級時,為什麼很長時間都沒有成功建立資料索引?

1秒內大約可以為600個增量檔案建立索引。您可以結合Bucket內的檔案數量,預估建立索引所需時間。

如何查詢指定首碼/目錄下的檔案總大小?

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列, 選擇文件管理 > 數據索引

  4. 檔案名稱設定為首碼匹配,並輸入首碼匹配:random_files/,其他參數保留預設設定。

    image

  5. 設定輸出方式

    • 對象排序方式選擇按照預設排序排列。

    • 資料彙總選擇按照檔案大小求和輸出。

      image

  6. 單擊立即查詢,可以看到最終統計到的random_files/目錄下所有檔案和總大小結果。

    image

相關文檔

標量檢索支援多項過濾條件,例如檔案最後修改時間、儲存類型、讀寫權限、檔案大小等。如果您希望從OSS Bucket的海量Object中篩選出指定時間範圍內的Object,請參見如何篩選OSS指定時間範圍內的檔案