本指南介绍了 Google Drive API 如何支持多种搜索文件和文件夹的方式。
您可以使用 list 方法返回
files 资源中的云端硬盘用户的所有或部分文件和文件夹。您还可以使用 list
方法检索某些资源方法(例如
get 和 update 方法)所需的 fileId。
使用 fields 参数
如果您想指定要在响应中返回的字段,可以使用
fields system
parameter
使用 files 资源的任何方法。如果您省略 fields 参数,服务器会返回特定于该方法的默认字段集。例如,
list 方法仅返回每个文件的 kind、id、
name、mimeType 和 resourceKey 字段。如需返回不同的
字段,请参阅返回特定字段。
按 ID 获取文件
如需获取文件,请使用 get 方法以及
files 资源中的 fileId 路径参数。
如果您不知道文件 ID,可以使用 list all files list
方法列出所有文件。
该方法会将文件作为 files 资源的实例返回。如果您提供 alt=media 参数,则响应会在响应正文中包含文件内容。如需下载 Blob 文件,请参阅下载 Blob 文件内容。
如需确认下载已知恶意软件或其他
滥用文件的风险,请将
acknowledgeAbuse查询参数设置为true。此字段仅在设置了 alt=media 参数且用户是文件所有者或文件所在的共享云端硬盘的组织者时适用。
列出“我的云端硬盘”中的所有文件和文件夹
使用不带任何参数的 list 方法返回当前用户的“我的云端硬盘”中的所有文件和文件夹。
以下 curl 命令展示了如何列出所有文件:
curl -X GET \
'https://www.googleapis.com/drive/v3/files' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Accept: application/json'
将 ACCESS_TOKEN 替换为已获授权的 OAuth 2.0 访问令牌。
在“我的云端硬盘”中搜索特定文件和文件夹
如需在当前用户的“我的
云端硬盘”中搜索特定的一组文件或文件夹,请将 list 方法与查询字符串 q 字段搭配使用,通过组合
一个或多个搜索字词来过滤要返回的文件。
查询字符串语法包含以下三个部分:
query_term operator values
其中:
query_term是要搜索的查询字词或字段。operator用于指定查询字词的条件。values是您要用于过滤搜索结果的特定值。
例如,以下查询字符串通过设置 MIME 类型来过滤搜索结果,使其仅返回 文件夹:
mimeType = 'application/vnd.google-apps.folder'
如需查看所有文件查询字词,请参阅特定于文件的查询字词。
如需查看可用于构建查询的所有查询运算符,请参阅查询 运算符。
查询字符串示例
下表列出了一些基本查询字符串的示例。实际代码因您用于搜索的客户端库而异。
您还必须对文件名中的特殊字符进行转义,以确保查询正常运行。例如,如果文件名同时包含撇号
(') 和反斜杠 ("\") 字符,请使用反斜杠对其进行转义:name
contains 'quinn\'s paper\\essay'。
| 要查询的内容 | 示例 |
|---|---|
字符串匹配运算符 (contains) |
|
| 包含“hello”一词的文件 | fullText contains 'hello' |
| 包含确切短语“hello world”的文件 | fullText contains '"hello world"' |
| 查询中包含“\”字符(例如“\authors”)的文件 | fullText contains '\\authors' |
| 名称中包含“budget”的文件 | name contains 'budget' |
等式和不等式运算符 (=, !=) |
|
| 名称为“hello”的文件 | name = 'hello' |
| 文件夹文件 | mimeType = 'application/vnd.google-apps.folder' |
| 非文件夹文件 | mimeType != 'application/vnd.google-apps.folder' |
| 已加星标的文件 | starred = true |
| 位于回收站中的文件 | trashed = true |
| 不在回收站中的文件 | trashed = false |
| 指向特定文件 ID 的快捷方式 | shortcutDetails.targetId = '1987654321' |
| 未与任何人或网域共享的文件(私密文件,或与特定用户或群组共享的文件) | visibility = 'limited' |
| 只要知道链接就可以访问的文件 | visibility = 'anyoneWithLink' |
| 可在网络上公开发现的文件 | visibility = 'anyoneCanFind' |
比较运算符 (>, >=, <, <=) |
|
| 在给定日期之后修改的文件(默认时区为 UTC) | modifiedTime > '2012-06-04T12:00:00' |
| 在 2023 年 1 月 1 日之后创建的文件 | createdTime > '2023-01-01T00:00:00' |
| 在 2023 年 1 月 1 日之前修改的文件 | modifiedTime < '2023-01-01T00:00:00' |
集合成员资格运算符 (in) |
|
集合中的直接子文件(例如 parents 集合中的文件夹 ID) |
'1234567' in parents |
| 应用数据文件夹中的文件 | 'appDataFolder' in parents |
| 用户“test@example.org”是所有者的文件 | 'test@example.org' in owners |
| 用户“test@example.org”具有写入权限的文件 | 'test@example.org' in writers |
| 群组“group@example.org”的成员具有写入权限的文件 | 'group@example.org' in writers |
| 用户“test@example.org”具有读取权限的文件 | 'test@example.org' in readers |
集合匹配运算符 (has) |
|
| 具有对所有应用可见的自定义文件属性的文件 | properties has { key='mass' and value='1.3kg' } |
| 具有对请求应用私有的自定义文件属性的文件 | appProperties has { key='additionalID' and value='8e8aceg2af2ge72e78' } |
| 具有键为“department”的自定义文件属性的文件(无论值如何) | properties has { key='department' } |
逻辑运算符 (and, or, not) |
|
| 名称中包含“hello”和“goodbye”字样的文件 | name contains 'hello' and name contains 'goodbye' |
| 名称中不包含“hello”字样的文件 | not name contains 'hello' |
| 包含文本“important”且位于回收站中的文件 | fullText contains 'important' and trashed = true |
| 不包含“hello”字样的文件 | not fullText contains 'hello' |
| 在特定日期之后修改的图片或视频文件 | modifiedTime > '2012-06-04T12:00:00' and (mimeType contains 'image/' or mimeType contains 'video/') |
| 名称中包含“hello”且与已获授权的用户共享的文件 | sharedWithMe and name contains 'hello' |
| 文件夹或快捷方式文件 | mimeType = 'application/vnd.google-apps.folder' or mimeType = 'application/vnd.google-apps.shortcut' |
| 名称为“Project Plan”且不在回收站中的文件 | name = 'Project Plan' and trashed = false |
| 特定文件夹中的直接子文件且不在回收站中 | '1234567' in parents and trashed = false |
使用客户端库过滤搜索结果
以下代码示例展示了如何使用客户端库将搜索结果过滤为 JPEG 文件的文件名和 ID。此示例使用 mimeType 查询字词将结果缩小到 image/jpeg 类型的文件。它还将
spaces设置为drive,以进一步将搜索范围缩小到云端硬盘
空间。当 nextPageToken 返回 null 时,表示没有更多结果。
Java
Python
Node.js
PHP
列出公共文件夹中的文件
如需在公开共享的文件夹(访问权限设置为
“知道链接的任何人”或“在网络上公开”)中搜索或列出文件,请使用 list 方法files,并将 q 查询
参数设置为按 parents 集合中的文件夹 ID 进行过滤:
'FOLDER_ID' in parents and trashed = false
列出公共文件夹中的文件时,您可以使用
API 密钥(而不是 OAuth 2.0
用户凭据)对请求进行身份验证。如果文件夹位于共享云端硬盘中,您还必须在请求中设置 supportsAllDrives=true 和 includeItemsFromAllDrives=true。
以下代码示例展示了如何列出公共文件夹中的文件:
Node.js
/**
* List files in a public folder using an API key.
* @param {string} folderId The ID of the public folder.
* @param {string} apiKey Your Google Cloud API key.
* @return {Promise<Array>} The list of files.
*/
async function listPublicFolder(folderId, apiKey) {
const {google} = require('googleapis');
const service = google.drive({version: 'v3', auth: apiKey});
try {
const response = await service.files.list({
q: `'${folderId}' in parents and trashed = false`,
fields: 'nextPageToken, files(id, name, mimeType)',
supportsAllDrives: true,
includeItemsFromAllDrives: true,
});
const files = response.data.files;
console.log('Files:');
for (const file of files) {
console.log(`${file.name} (${file.id})`);
}
return files;
} catch (err) {
// TODO(developer): Handle error
console.error(err);
}
}
curl
curl -G \
'https://www.googleapis.com/drive/v3/files' \
--data-urlencode "q='FOLDER_ID' in parents and trashed = false" \
--data-urlencode 'supportsAllDrives=true' \
--data-urlencode 'includeItemsFromAllDrives=true' \
--data-urlencode 'fields=nextPageToken,files(id,name,mimeType)' \
--data-urlencode 'key=API_KEY' \
-H 'Accept: application/json'
替换以下内容:
- FOLDER_ID:公共文件夹的 ID。
- API_KEY:项目的 API 密钥。
以递归方式搜索后代文件夹和文件
parents 查询字词仅返回位于指定文件夹中的直接子文件和文件夹。Drive API 不提供查询运算符或参数,以便在单个 API 调用中以递归方式搜索后代子文件夹树。
如需搜索文件夹及其所有后代子文件夹和文件,您的应用必须执行客户端树遍历:
- 使用
'FOLDER_ID' in parents and trashed = false查询目标文件夹的直接子项。 - 通过过滤
mimeType = 'application/vnd.google-apps.folder'的结果来识别子文件夹。 - 以递归或迭代方式查询每个子文件夹的 ID,以检索其内容。
以下代码示例展示了如何以递归方式搜索文件夹及其后代:
Node.js
/**
* Recursively searches a folder and all descendant subfolders for files.
* @param {string} folderId The ID of the starting folder.
* @param {Object} authClient An authorized OAuth 2.0 client.
* @return {Promise<Array>} The list of all descendant files.
*/
async function searchFolderRecursively(folderId, authClient) {
const {google} = require('googleapis');
const service = google.drive({version: 'v3', auth: authClient});
const allFiles = [];
const foldersToSearch = [folderId];
try {
while (foldersToSearch.length > 0) {
const currentFolderId = foldersToSearch.pop();
let pageToken = null;
do {
const response = await service.files.list({
q: `'${currentFolderId}' in parents and trashed = false`,
fields: 'nextPageToken, files(id, name, mimeType)',
pageSize: 1000,
supportsAllDrives: true,
includeItemsFromAllDrives: true,
pageToken: pageToken,
});
const files = response.data.files || [];
for (const file of files) {
if (file.mimeType === 'application/vnd.google-apps.folder') {
foldersToSearch.push(file.id);
} else {
allFiles.push(file);
}
}
pageToken = response.data.nextPageToken;
} while (pageToken);
}
return allFiles;
} catch (err) {
// TODO(developer): Handle error
console.error(err);
throw err;
}
}
Python
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
def search_folder_recursively(folder_id, creds):
"""Recursively searches a folder and all descendant subfolders for
files.
Args:
folder_id: The ID of the starting folder.
creds: An authorized OAuth 2.0 credentials object.
Returns:
A list of all descendant file resources.
"""
service = build("drive", "v3", credentials=creds)
all_files = []
folders_to_search = [folder_id]
try:
while folders_to_search:
current_folder_id = folders_to_search.pop()
page_token = None
while True:
response = (
service.files()
.list(
q=f"'{current_folder_id}' in parents and trashed = false",
fields="nextPageToken, files(id, name, mimeType)",
pageSize=1000,
supportsAllDrives=True,
includeItemsFromAllDrives=True,
pageToken=page_token,
)
.execute()
)
for item in response.get("files", []):
if (
item.get("mimeType")
== "application/vnd.google-apps.folder"
):
folders_to_search.append(item.get("id"))
else:
all_files.append(item)
page_token = response.get("nextPageToken")
if not page_token:
break
return all_files
except HttpError as error:
# TODO(developer): Handle error
print(f"An error occurred: {error}")
return None
搜索具有自定义属性的文件
如需搜索具有自定义文件属性的文件,请将 properties 或 appProperties 搜索查询字词与键和值搭配使用。例如,如需搜索对请求应用私有的自定义文件属性(名为 additionalID,值为 8e8aceg2af2ge72e78):
appProperties has { key='additionalID' and value='8e8aceg2af2ge72e78' }
如需了解详情,请参阅添加自定义文件 属性。
按标签或字段值搜索文件
如需搜索具有特定标签的文件,请将 labels 搜索查询字词与特定标签 ID 搭配使用。
如需搜索应用了特定标签的文件:
'labels/LABEL_ID' in labels
如需搜索未应用特定标签的文件:
not 'labels/LABEL_ID' in labels
如需根据特定标签字段值搜索文件:
labels/LABEL_ID.FIELD_ID = 'VALUE'
如果成功,响应正文将包含与查询匹配的所有文件实例。如需了解详情,请参阅搜索具有特定标签或 字段值的文件。
跨语料库搜索
默认情况下,使用 list 方法时,corpora 查询参数
会设置为 user 项集合。如需搜索其他项集合(例如与 domain 共享的项集合),您必须明确设置 corpora 参数。
您可以在单个查询中搜索多个语料库;但是,如果组合的语料库过大,API 可能会返回不完整的结果。检查响应正文中的
incompleteSearch
字段。如果该字段为 true,则表示省略了一些文档。如需解决此问题,请将 corpora 缩小为使用 user 或 drive。
在
orderBy查询
参数与list方法一起使用时,请避免对
大型项集合使用createdTime键进行查询,因为这需要额外的处理,并且可能会导致
超时或其他问题。如需对大型项集合进行与时间相关的排序,您可以使用 modifiedTime,因为它经过优化,可以处理这些查询。
例如,将 orderBy 设置为 modifiedTime(或 modifiedTime desc)。
如果您省略 orderBy 查询参数,则没有默认排列顺序,并且项会以任意顺序返回。