文档

数据索引(Data Indexing)

更新时间:

数据索引是OSS对外提供的文件(Object)元数据索引能力。您可以利用Object的元数据自定义索引的条件,从而快速获取Object列表。数据索引可以帮助您更好地管理与了解数据结构,方便您后续查询、统计和管理Object。

使用场景

基于数据审计或者数据监管等原因,您可能需要从存放于OSS存储空间(Bucket)内多达上亿的海量Object中查找符合特定条件的Object。Object本身包含大量的元数据,例如Object名称、Object ETag、Object存储类型、Object大小、Object标签、Object最后修改时间等。通过元数据索引功能,您可以在查找目标Object时结合具体的业务场景,通过组合简单查询条件以及聚合操作,提升查找目标Object的效率。

注意事项

  • 地域限制

    仅华东1(杭州)以及澳大利亚(悉尼)地域的存储空间支持使用数据索引功能。无地域属性的存储空间不支持使用数据索引功能。

  • Bucket限制

    默认只支持为文件数量在1亿以下的Bucket开启元数据管理功能。

  • 费用说明

    数据索引目前是公测阶段。使用数据索引功能时,需要开启元数据管理。开启元数据管理功能会产生Object的Meta管理费用以及Bucket的查询费用,但公测期间暂不收费。关于数据索引计费项的更多信息,请参见数据索引费用

  • 建立索引所需时间

    开启元数据管理功能时,建立索引所需时间与Bucket内存量文件数量成正比。文件数量越多,建立索引的时间越长。

  • 分片上传

    对于通过分片上传生成的Object,则查询结果中只显示已通过CompleteMultipartUpload操作将碎片(Part)合成的完整Object,不显示已初始化但未完成(Complete)或者未中止(Abort)的碎片。

操作步骤

使用OSS控制台

  1. 登录OSS管理控制台

  2. 单击Bucket 列表,然后单击目标Bucket名称。

  3. 在左侧导航栏, 选择文件管理 > 数据索引

  4. 数据索引页面,打开元数据管理开关。

    开启元数据管理需要等待一定的时间,具体等待时长取决于Bucket中Object的数量。

  5. 设置Object基础过滤条件。

    对象基础过滤条件区域,按需设置以下基础过滤条件。

    过滤条件

    说明

    存储类型

    默认选中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。

  6. 可选:设置Object其他过滤条件。

    如果您需要对查询结果中的Object进行排序或者使用标签过滤等,请单击展开更多过滤条件

    • 设置Object排序方式。

      对象排序方式区域,结合最后修改时间文件名文件大小的筛选条件,选择查询结果中Object按照这三种筛选条件进行升序降序排列。

    • 设置Object标签过滤条件。

      对象标签过滤区域,输入您希望在查询结果中显示的Object对应的ETag或标签信息。

      • ETag仅支持精确匹配。可输入多个ETag,每行一个。

      • 以键值对(Key-Value)的形式指定对象标签。对象标签的Key和Value均区分大小写。关于标签规则的更多信息,请参见对象标签

    • 设置对象数据聚合方式。

      如果您希望在查询结果中对数据进行分类统计,例如统计所有文件大小、去重统计文件存储类型等,请添加数据聚合方式。

使用阿里云SDK

仅Java SDK、Python SDK以及Go SDK支持通过数据索引功能查询满足指定条件的Object。使用数据索引功能前,您需要为指定Bucket开启元数据管理功能。关于数据索引的代码示例,请参见SDK简介

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import java.util.ArrayList;
import java.util.List;

public class Demo {

    // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
    private static String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
    // 填写Bucket名称,例如examplebucket。
    private static String bucketName = "examplebucket";

    public static void main(String[] args) throws Exception {
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        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();
        }
    }
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import MetaQuery, AggregationsRequest
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())

# Endpoint以杭州为例,其它Region请按实际情况填写。
# 填写Bucket名称,例如examplebucket。
bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')

# 查询满足指定条件的Object,并按照指定字段和排序方式列举Object信息。
# 指定查询小于1 MB的文件,且最多返回十个结果,返回结果按升序排列。
do_meta_query_request = MetaQuery(max_results=10, query='{"Field": "Size","Value": "1048576","Operation": "lt"}', sort='Size', order='asc')
result = bucket.do_bucket_meta_query(do_meta_query_request)

# 打印Object名称。
print(result.files[0].file_name)
# 打印Object对应的ETag。
print(result.files[0].etag)
# 打印Object类型。
print(result.files[0].oss_object_type)
# 打印Object存储类型。
print(result.files[0].oss_storage_class)
# 打印Object的64位CRC值。
print(result.files[0].oss_crc64)
# 打印Object的访问权限。
print(result.files[0].object_acl)
package main

import (
    "fmt"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "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实例。
    // yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }    
    // 指定查询大于30字节的文件,且最多返回十个结果,返回结果按升序排列。
    query := oss.MetaQuery{
        NextToken: "",
        MaxResults: 10,
        Query: `{"Field": "Size","Value": "30","Operation": "gt"}`,
        Sort: "Size",
        Order: "asc",
    }
    // 查询满足指定条件的Object,并按照指定字段和排序方式列举Object信息。
    result,err := client.DoMetaQuery("examplebucket",query)
    if err != nil {
        fmt.Println("Error:", err)
        os.Exit(-1)
    }
    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)
        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)
        }
    }
}

使用REST API

如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见DoMetaQuery

常见问题

Bucket内文件数量达到上亿级别时,为什么很长时间都没有成功建立数据索引?

1秒内大约可以为600个文件建立索引。您可以结合Bucket内的文件数量,预估建立索引所需时间。

  • 本页导读 (1)
文档反馈