חיפוש קבצים ותיקיות

במדריך הזה מוסבר איך ממשק Google Drive API תומך בכמה דרכים לחיפוש קבצים ותיקיות.

אפשר להשתמש ב-method‏ list במשאב files כדי להחזיר את כל הקבצים והתיקיות של משתמש ב-Drive, או חלק מהם. אפשר גם להשתמש ב-method‏ list כדי לאחזר את fileId שנדרש ל-methods מסוימות של משאבים (כמו get ו-update).

שימוש בפרמטר fields

אם רוצים לציין את השדות שיוחזרו בתגובה, אפשר להגדיר את הפרמטר של המערכת fields בכל שיטה של המשאב files. אם משמיטים את הפרמטר fields, השרת מחזיר קבוצת ברירת מחדל של שדות שספציפיים לשיטה. לדוגמה, ה-method‏ list מחזירה רק את השדות kind, id, name, mimeType ו-resourceKey לכל קובץ. כדי להחזיר שדות שונים, אפשר לעיין במאמר החזרת שדות ספציפיים.

אחזור קובץ לפי מזהה

כדי לקבל קובץ, משתמשים ב-method ‏get במשאב files עם פרמטר של הנתיב fileId. אם אתם לא יודעים את מזהה הקובץ, אתם יכולים להציג את כל הקבצים באמצעות ה-method‏ list.

השיטה מחזירה את הקובץ כמופע של משאב files. אם תציינו את הפרמטר alt=media, התשובה תכלול את תוכן הקובץ בגוף התשובה. כדי להוריד קובץ blob, אפשר לעיין במאמר בנושא הורדת תוכן של קובץ blob.

כדי לאשר את הסיכון בהורדת תוכנות זדוניות ידועות או קבצים פוגעניים אחרים, מגדירים את פרמטר השאילתה acknowledgeAbuse לערך true. השדה הזה רלוונטי רק כשמגדירים את הפרמטר alt=media והמשתמש הוא הבעלים של הקובץ או המארגן של האחסון השיתופי שבו הקובץ נמצא.

הצגת רשימה של כל הקבצים והתיקיות בתיקיית "האחסון שלי"

משתמשים ב-method‏ 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 מורשה.

חיפוש קבצים ותיקיות ספציפיים בתיקיית "האחסון שלי"

כדי לחפש קבוצה ספציפית של קבצים או תיקיות בתיקיית 'האחסון שלי' של המשתמש הנוכחי, משתמשים בשדה q query עם השיטה list כדי לסנן את הקבצים שיוחזרו על ידי שילוב של מונח חיפוש אחד או יותר.

התחביר של מחרוזת השאילתה כולל את שלושת החלקים הבאים:

query_term operator values

כאשר:

  • ‫query_term הוא מונח השאילתה או השדה שרוצים לחפש.

  • ‫operator מציין את התנאי למונח החיפוש.

  • values הם הערכים הספציפיים שאתם רוצים להשתמש בהם כדי לסנן את תוצאות החיפוש.

לדוגמה, מחרוזת השאילתה הבאה מסננת את החיפוש כך שיוחזרו רק תיקיות, על ידי הגדרת סוג MIME:

mimeType = 'application/vnd.google-apps.folder'

כדי לראות את כל מונחי השאילתות של הקבצים, עיינו בקטע מונחי שאילתות ספציפיים לקבצים.

כדי לראות את כל האופרטורים של השאילתות שאפשר להשתמש בהם כדי ליצור שאילתה, ראו אופרטורים של שאילתות.

דוגמאות למחרוזות שאילתה

בטבלה הבאה מפורטות דוגמאות למחרוזות שאילתה בסיסיות. הקוד בפועל משתנה בהתאם לספריית הלקוח שבה אתם משתמשים לחיפוש.

כדי שהשאילתה תפעל כמו שצריך, צריך גם להוסיף תווי בריחה (escape) לתווים מיוחדים בשמות הקבצים. לדוגמה, אם שם הקובץ מכיל גם גרש (') וגם לוכסן הפוך ("\"), צריך להשתמש בלוכסן הפוך כדי לסמן אותם כתווים מיוחדים: name contains 'quinn\'s paper\\essay'.

מה צריך לחפש דוגמה
אופרטור התאמה למחרוזת (contains)
קבצים שמכילים את המילה hello fullText contains 'hello'
קבצים שמכילים את הביטוי המדויק "Hello World" fullText contains '"hello world"'
קובצים עם שאילתה שמכילה את התו '\' (לדוגמה, '\authors') fullText contains '\\authors'
קבצים שהשם שלהם מכיל את המילה "תקציב" name contains 'budget'
אופרטורים של שוויון ואי-שוויון (=, !=)
קבצים עם השם "שלום" name = 'hello'
קבצים שהם תיקיות mimeType = 'application/vnd.google-apps.folder'
קבצים שהם לא תיקיות mimeType != 'application/vnd.google-apps.folder'
קבצים שמסומנים בכוכב starred = true
קבצים שנמצאים באשפה trashed = true
קבצים שלא נמצאים באשפה trashed = false
קיצורי דרך שמפנים למזהה קובץ ספציפי shortcutDetails.targetId = '1987654321'
קבצים שלא שותפו עם אף אחד או עם אף דומיין (פרטיים, או ששותפו עם משתמשים או קבוצות ספציפיים) visibility = 'limited'
קבצים שנגישים לכל מי שיש לו את הקישור visibility = 'anyoneWithLink'
קבצים שגלויים לכולם באינטרנט visibility = 'anyoneCanFind'
אופרטורים להשוואה (>, ‏ >=, ‏ <, ‏ <=)
קבצים ששונו אחרי תאריך מסוים (אזור הזמן שמוגדר כברירת מחדל הוא UTC) modifiedTime > '2012-06-04T12:00:00'
קבצים שנוצרו אחרי 1 בינואר 2023 createdTime > '2023-01-01T00:00:00'
קבצים ששונו לפני 1 בינואר 2023 modifiedTime < '2023-01-01T00:00:00'
אופרטור חברות באוסף (in)
קבצים שהם צאצאים ישירים באוסף (לדוגמה, מזהה התיקייה באוסף parents) '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'
קבצים שהשם שלהם לא מכיל את המילה "שלום" not name contains 'hello'
קבצים שמכילים את הטקסט "חשוב" ונמצאים באשפה fullText contains 'important' and trashed = true
קבצים שלא מכילים את המילה "שלום" 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. בדוגמה הזו נעשה שימוש במונח השאילתה mimeType כדי לצמצם את התוצאות לקבצים מהסוג image/jpeg. הוא גם מגדיר את spaces ל-drive כדי לצמצם עוד יותר את החיפוש למרחב של Drive. כשהערך של nextPageToken הוא null, אין יותר תוצאות.

Java

drive/snippets/drive_v3/src/main/java/SearchFile.java
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/* Class to demonstrate use-case of search files. */
public class SearchFile {

  /**
   * Search for specific set of files.
   *
   * @return search result list.
   * @throws IOException if service account credentials file not found.
   */
  public static List<File> searchFile() throws IOException {
           /*Load pre-authorized user credentials from the environment.
           TODO(developer) - See https://developers.google.com/identity for
           guides on implementing OAuth2 for your application.*/
    GoogleCredentials credentials = GoogleCredentials.getApplicationDefault()
        .createScoped(Arrays.asList(DriveScopes.DRIVE_FILE));
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

    // Build a new authorized API client service.
    Drive service = new Drive.Builder(new NetHttpTransport(),
        GsonFactory.getDefaultInstance(),
        requestInitializer)
        .setApplicationName("Drive samples")
        .build();

    List<File> files = new ArrayList<File>();

    String pageToken = null;
    do {
      FileList result = service.files().list()
          .setQ("mimeType='image/jpeg'")
          .setSpaces("drive")
          .setFields("nextPageToken, files(id, title)")
          .setPageToken(pageToken)
          .execute();
      for (File file : result.getFiles()) {
        System.out.printf("Found file: %s (%s)\n",
            file.getName(), file.getId());
      }

      files.addAll(result.getFiles());

      pageToken = result.getNextPageToken();
    } while (pageToken != null);

    return files;
  }
}

Python

drive/snippets/drive-v3/file_snippet/search_file.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def search_file():
  """Search file in drive location

  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()

  try:
    # create drive api client
    service = build("drive", "v3", credentials=creds)
    files = []
    page_token = None
    while True:
      # pylint: disable=maybe-no-member
      response = (
          service.files()
          .list(
              q="mimeType='image/jpeg'",
              spaces="drive",
              fields="nextPageToken, files(id, name)",
              pageToken=page_token,
          )
          .execute()
      )
      for file in response.get("files", []):
        # Process change
        print(f'Found file: {file.get("name")}, {file.get("id")}')
      files.extend(response.get("files", []))
      page_token = response.get("nextPageToken", None)
      if page_token is None:
        break

  except HttpError as error:
    print(f"An error occurred: {error}")
    files = None

  return files


if __name__ == "__main__":
  search_file()

Node.js

drive/snippets/drive_v3/file_snippets/search_file.js
import {GoogleAuth} from 'google-auth-library';
import {google} from 'googleapis';

/**
 * Searches for files in Google Drive.
 * @return {Promise<object[]>} A list of files.
 */
async function searchFile() {
  // Authenticate with Google and get an authorized client.
  // TODO (developer): Use an appropriate auth mechanism for your app.
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive',
  });

  // Create a new Drive API client (v3).
  const service = google.drive({version: 'v3', auth});

  // Search for files with the specified query.
  const result = await service.files.list({
    q: "mimeType='image/jpeg'",
    fields: 'nextPageToken, files(id, name)',
    spaces: 'drive',
  });

  // Print the name and ID of each found file.
  (result.data.files ?? []).forEach((file) => {
    console.log('Found file:', file.name, file.id);
  });

  return result.data.files ?? [];
}

PHP

drive/snippets/drive_v3/src/DriveSearchFiles.php
<?php
use Google\Client;
use Google\Service\Drive;
function searchFiles()
{
    try {
        $client = new Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope(Drive::DRIVE);
        $driveService = new Drive($client);
        $files = array();
        $pageToken = null;
        do {
            $response = $driveService->files->listFiles(array(
                'q' => "mimeType='image/jpeg'",
                'spaces' => 'drive',
                'pageToken' => $pageToken,
                'fields' => 'nextPageToken, files(id, name)',
            ));
            foreach ($response->files as $file) {
                printf("Found file: %s (%s)\n", $file->name, $file->id);
            }
            array_push($files, $response->files);

            $pageToken = $response->pageToken;
        } while ($pageToken != null);
        return $files;
    } catch(Exception $e) {
       echo "Error Message: ".$e;
    }
}

הצגת רשימת קבצים בתיקייה ציבורית

כדי לחפש קבצים בתיקייה ששותפה עם כולם (שהגישה אליה מוגדרת כ'כל מי שיש לו את הקישור' או 'ציבורי באינטרנט'), צריך להשתמש בשיטה list במשאב files עם פרמטר השאילתה q שהוגדר לסינון לפי מזהה התיקייה באוסף parents:

'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: המזהה של התיקייה הציבורית.
  • ‫API_KEY: מפתח ה-API של הפרויקט.

השאילתה parents מחזירה רק קבצים ותיקיות שהם צאצאים ישירים של התיקייה שצוינה. ‫Drive API לא מספק אופרטור או פרמטר של שאילתה כדי לחפש באופן רקורסיבי בעצי תיקיות משנה צאצאים בקריאה אחת ל-API.

כדי לחפש תיקייה ואת כל תיקיות המשנה והקבצים שנגזרים ממנה, האפליקציה צריכה לבצע מעבר על העץ בצד הלקוח:

  1. שולחים שאילתה על הצאצאים הישירים של תיקיית היעד באמצעות 'FOLDER_ID' in parents and trashed = false.
  2. מזהים תיקיות משנה על ידי סינון התוצאות שבהן mimeType = 'application/vnd.google-apps.folder'.
  3. שולחים שאילתה באופן רקורסיבי או איטרטיבי על המזהה של כל תיקיית צאצא כדי לאחזר את התוכן שלה.

בדוגמאות הקוד הבאות אפשר לראות איך לחפש בתיקייה ובצאצאים שלה באופן רקורסיבי:

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 של שאילתת החיפוש עם מזהה תווית ספציפי.

כדי לחפש קבצים שחלה עליהם תווית ספציפית:

'labels/LABEL_ID' in labels

כדי לחפש קבצים שלא הוחלה עליהם תווית מסוימת:

not 'labels/LABEL_ID' in labels

כדי לחפש קבצים לפי ערך ספציפי של שדה בתווית:

labels/LABEL_ID.FIELD_ID = 'VALUE'

אם הפעולה מצליחה, גוף התשובה מכיל את כל מופעי הקבצים שתואמים לשאילתה. מידע נוסף זמין במאמר חיפוש קבצים עם תווית או ערך שדה ספציפיים.

חיפוש בכל גוף המסמכים

כברירת מחדל, אוסף הפריטים user מוגדר בפרמטר השאילתה corpora כשמשתמשים ב-method ‏list. כדי לחפש באוספים אחרים של פריטים, כמו אלה ששותפו עם domain, צריך להגדיר במפורש את הפרמטר corpora.

אפשר לחפש בכמה מאגרים בשאילתה אחת, אבל אם המאגרים המשולבים גדולים מדי, יכול להיות שה-API יחזיר תוצאות חלקיות. בודקים את השדה incompleteSearch בגוף התשובה. אם הערך הוא true, סימן שחלק מהמסמכים הושמטו. כדי לפתור את הבעיה, צריך לצמצם את corpora כך שיכלול רק את user או את drive.

כשמשתמשים בפרמטר השאילתה orderBy ב-method‏ list, מומלץ להימנע משימוש במפתח createdTime לשאילתות על אוספי פריטים גדולים, כי הוא דורש עיבוד נוסף ועלול לגרום לזמן קצוב לתפוגה או לבעיות אחרות. כדי למיין לפי זמן באוספים גדולים של פריטים, אפשר להשתמש ב-modifiedTime כי הוא מותאם לטיפול בשאילתות כאלה. לדוגמה, מגדירים את orderBy לערך modifiedTime (או modifiedTime desc).

אם משמיטים את הפרמטר orderBy של השאילתה, אין סדר מיון שמוגדר כברירת מחדל והפריטים מוחזרים באופן שרירותי.