如果您希望从OSS Bucket的海量Object中筛选出指定时间范围内的Object,您可以使用数据索引功能。使用数据索引功能时,通过将Object最后修改时间的起始和结束日期作为检索条件,提升查询任务的执行效率,适用于审计追踪、数据同步、周期性备份、成本分析或其他业务场景中对时效性文件的精准获取需求。
使用场景
审计与合规性检查
企业或组织可能需要定期回顾指定时间范围内的数据活动,以确保符合内部数据管理政策、行业法规或监管要求。查询指定时间范围内上传的文件可以协助数据生命周期管理、追踪数据生成与变更历史,以及数据审计过程。
数据备份与恢复
在指定备份策略或执行数据恢复操作时,可能仅需关注某个时间窗口内的新增或更新文件。例如,在执行增量备份时,仅需备份自上次备份以来新上传或修改的文件。通过查询指定时间范围内的上传文件,可以明确需要备份的对象,节省存储空间和传输成本。
数据分析与报表生成
对于涉及大数据分析、日志处理或业务报表的应用,可能需要定期(如每日、每周、每月)处理某一时间段内产生的新数据。查询特定时间范围内的文件可以快速定位到待分析的数据集,简化数据提取流程。
内容管理系统同步
如果OSS存储的是网站内容、媒体资产或文档库,内容管理系统可能需要定期抓取或同步指定时间范围内新增或更新的文件,以保持网站内容的时效性和完整性。
成本优化与资源清理
为了控制存储成本或遵循数据保留策略,企业可能会定期审查并清理不再需要的旧文件。查询并列出指定时间内未更新的文件有助于识别不再需要保留的文件,确保资源的有效利用。
故障排查与问题追溯
在排查系统故障、数据丢失或异常行为时,技术人员可能需要回溯特定时间段内的数据变动情况。查询该时段内上传的文件有助于快速定位可能导致问题的文件版本或操作记录。
协作与版本控制
在多用户协作环境中,可能需要查看或恢复某个时间段内其他成员上传的文件版本。时间范围查询有助于历史版本浏览、对比或恢复到特定时间点的状态。
操作步骤
使用OSS控制台
登录OSS管理控制台。
单击Bucket 列表,然后单击目标Bucket名称。
在左侧导航栏, 选择文件管理 > 数据索引。
在数据索引页面,打开元数据管理开关。
开启元数据管理需要等待一定的时间,具体等待时长取决于Bucket中Object的数量。
在对象基础过滤条件区域,指定最后修改时间的起始和结束日期(精确到秒),其他参数保留默认配置。
在对象排序方式区域,选择按文件名升序排列。
单击查询。
使用阿里云SDK
仅Java SDK、Python SDK以及Go SDK支持通过数据索引功能查询满足指定条件的Object。使用数据索引功能前,您需要为指定Bucket开启元数据管理功能。
Java
package com.aliyun.sts.sample;
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.*;
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 {
// 设置返回的文件最大个数为100。
int maxResults = 100;
// 指定查询最后更新时间在2023年12月01日至2024年03月31日范围内的文件。
String query = "{\n" +
" \"SubQueries\":[\n" +
" {\n" +
" \"Field\":\"FileModifiedTime\",\n" +
" \"Value\": \"2023-12-01T00:00:00.000+08:00\",\n" +
" \"Operation\":\"gt\"\n" +
" }, \n" +
" {\n" +
" \"Field\":\"FileModifiedTime\",\n" +
" \"Value\": \"2024-03-31T23:59:59.000+08:00\",\n" +
" \"Operation\":\"lt\"\n" +
" }\n" +
" ],\n" +
" \"Operation\":\"and\"\n" +
"}";
// 指定返回结果按文件名升序排列。
String sort = "Filename";
DoMetaQueryRequest doMetaQueryRequest = new DoMetaQueryRequest(bucketName, maxResults, query, sort);
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());
}
}
}
}
} 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
# -*- 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', 'examplebucket0703')
# 指定查询最后更新时间在2023年12月01日至2024年03月31日范围内的文件,返回结果按文件名升序排列。
do_meta_query_request = MetaQuery(max_results=100, query='{"SubQueries":[{"Field":"FileModifiedTime","Value": "2023-12-01T00:00:00.000+08:00","Operation":"gt"}, {"Field":"FileModifiedTime","Value": "2024-03-31T23:59:59.000+08:00","Operation":"lt"}],"Operation":"and"}', sort='Filename', order='asc')
result = bucket.do_bucket_meta_query(do_meta_query_request)
for s in result.files:
print(s.file_name)
print(s.etag)
print(s.oss_object_type)
print(s.oss_storage_class)
print(s.oss_crc64)
print(s.object_acl)
Go
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("oss-cn-hangzhou.aliyuncs.com", "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 指定查询最后更新时间在2023年12月01日至2024年03月31日范围内的文件。
query := oss.MetaQuery{
NextToken: "",
MaxResults: 100,
Query: `{
"SubQueries":[
{
"Field":"FileModifiedTime",
"Value": "2023-12-01T00:00:00.000+08:00",
"Operation":"gt"
},
{
"Field":"FileModifiedTime",
"Value": "2024-03-31T23:59:59.000+08:00",
"Operation":"lt"
}
],
"Operation":"and"
}`,
// 指定返回结果按文件名升序排列。
Sort: "Filename",
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海量数据中快速筛选符合指定要求的条件,例如您希望查询所有读写权限为公共读的文件,或者所有小于64 KB的文件等,也可以通过数据索引来实现。更多信息,请参见数据索引。