Cercare documenti

Prima di iniziare

Per importare documenti di esempio in Document AI Warehouse, consulta la guida rapida.

Quando definisci gli schemi dei documenti e crei i documenti, è importante considerare quali proprietà vuoi definire e come verranno utilizzate con la ricerca, se non del tutto.

Contrassegna una proprietà come filtrabile se vuoi utilizzarla per includere o escludere una parte di documenti per una ricerca. Ad esempio, potresti rendere filtrabile una proprietà che rappresenta un "Fornitore" perché i tuoi utenti vogliono cercare le fatture di un fornitore specifico.

Se vuoi creare un istogramma (vedi l'esempio più avanti in questo argomento) su una proprietà, questa deve essere filtrabile.

Contrassegna una proprietà come ricercabile se contiene dati che gli utenti vorranno interrogare durante una ricerca per parole chiave.

La ricerca a testo intero è il processo di recupero di tutti i documenti che corrispondono alle parole chiave di ricerca nel testo ricercabile. L'utente fornisce un elenco di parole chiave (parole separate da uno spazio vuoto), presumibilmente digitate in un campo di ricerca nell'interfaccia utente. In Document AI Warehouse, le parole chiave vengono elaborate e convertite in una query appropriata. Questa elaborazione rimuove le stop word ("il", "in" e "un") e applica lo stemming alle parole rimanenti. Lo stemming riduce la parola a una versione comune della formulazione, in modo che le variazioni della parola corrispondano. Ad esempio: "lavoro", "lavorare", "lavorato".

Quali dati vengono inclusi nella ricerca?

  • Il plain_text del documento.
  • Se stai importando un oggetto Document AI, utilizza il cloud_ai_document.text incorporato.
  • Il display_name del documento.
  • Tutte le proprietà ricercabili.

La query supporta parzialmente la sintassi dello stile Google AIP. In particolare, la query supporta valori letterali, operatori logici, operatori di negazione, operatori di confronto e funzioni.

  • Valori letterali: un valore letterale semplice (esempi: "42", "Hugo") è un valore da confrontare. Esegue la ricerca nel testo completo del documento e nelle proprietà ricercabili.
  • Operatori logici: "AND", "and", "OR" e "or" sono operatori logici binari (esempio: "engineer OR developer").
  • Operatori di negazione: "NOT" e "!" sono operatori di negazione (esempio: "NOT software").
  • Operatori di confronto: supportano gli operatori di confronto binari =, !=, <, >, <= e >= per stringa, numerico, enum, booleano. Supportano anche l'operatore like ~~ per le stringhe. Fornisce funzionalità di ricerca semantica analizzando, applicando lo stemming ed espandendo i sinonimi rispetto alla query di input.

    Per specificare una proprietà nella query, l'espressione sul lato sinistro del confronto deve essere l'ID proprietà, incluso il parent. Il lato destro deve essere costituito da valori letterali. Ad esempio: \"projects/123/locations/us\".property_a < 1 corrisponde ai risultati la cui property_a è inferiore a 1 nel progetto 123 e nella località us. I valori letterali e l'espressione di confronto possono essere collegati in una singola query (esempio: software engineer \"projects/123/locations/us\".salary > 100).

  • Funzioni: le funzioni supportate sono LOWER([property_name]) per eseguire una corrispondenza senza distinzione tra maiuscole e minuscole e EMPTY([property_name]) per filtrare in base all'esistenza di una chiave.

  • Supporta le espressioni nidificate collegate tramite parentesi e operatori logici. L'operatore logico predefinito è AND se non sono presenti operatori tra le espressioni.

La query può essere utilizzata con altri filtri, ad esempio time_filters e folder_name_filter. Questi sono collegati con l'operatore AND in background.

Le query di ricerca possono essere filtrate in base a parametri aggiuntivi, ad esempio property, time, schema, folder e creator.

Chiamata a una richiesta di ricerca

Per chiamare il servizio di ricerca, devi utilizzare una richiesta di ricerca, definita come segue:

{
  "requestMetadata": {
    object (RequestMetadata)
  },
  "documentQuery": {
    object (DocumentQuery)
  },
  "offset": integer,
  "pageSize": integer,
  "pageToken": string,
  "orderBy": string,
  "histogramQueries": [
    {
      object (HistogramQuery)
    }
  ],
  "requireTotalSize": boolean,
  "totalResultSize": enum (TotalResultSize),
  "qaSizeLimit": integer
}

Il campo parent deve essere compilato nel seguente formato:

/projects/PROJECT_ID/locations/LOCATION

Risposta a una richiesta di ricerca

La risposta alla ricerca è definita come segue:

{
  "matchingDocuments": [
    {
      object (MatchingDocument)
    }
  ],
  "nextPageToken": string,
  "totalSize": integer,
  "metadata": {
    object (ResponseMetadata)
  },
  "histogramQueryResults": [
    {
      object (HistogramQueryResult)
    }
  ]
}

Query documento

Il campo document_query è definito come segue:

{
  "query": string,
  "isNlQuery": boolean,
  "customPropertyFilter": string,
  "timeFilters": [
    {
      object (TimeFilter)
    }
  ],
  "documentSchemaNames": [
    string
  ],
  "propertyFilter": [
    {
      object (PropertyFilter)
    }
  ],
  "fileTypeFilter": {
    object (FileTypeFilter)
  },
  "folderNameFilter": string,
  "queryContext": [
    string
  ],
  "documentCreatorFilter": [
    string
  ],
  "customWeightsMetadata": {
    object (CustomWeightsMetadata)
  }
}

Il campo query contiene le parole della query di ricerca dell'utente che ha effettuato la richiesta. In genere, queste provengono dal campo di ricerca nell'interfaccia utente.

Filtri

Document AI Warehouse offre una serie di filtri.

Filtro temporale dei documenti

Il filtro temporale di creazione e aggiornamento è esattamente quello che ti aspetteresti: trova i documenti che corrispondono alle parole chiave in un periodo di tempo specificato.

Un oggetto TimeFilter viene utilizzato per specificare l'intervallo di tempo ed è definito come segue:

{
  "timeRange": {
    object (Interval)
  },
  "timeField": enum (TimeField)
}

Nel campo time_field specifichi se l'intervallo di tempo specificato in time_range si riferisce alla data di creazione o all'ultima data di aggiornamento del documento.

Il campo time_range specifica l'intervallo di tempo come Interval. Un Interval è definito come:

{
  "startTime": string,
  "endTime": string
}

Filtro creator

Per cercare i documenti creati da uno o più utenti specifici, utilizza il filtro creator. Ad esempio:

  {
    document_query {
      query: "videogames director",
      documentCreatorFilter: [
        "diane@some_company.com",
        "frank@some_company.com",
      ],
    },
  }

Filtro proprietà

Il filtro proprietà ti consente di specificare i filtri su una qualsiasi delle proprietà specificate in uno schema, a condizione che la proprietà sia stata configurata come filtrabile.

Ad esempio, l'utilizzo dei filtri proprietà nel settore legale potrebbe filtrare una proprietà denominata COURT per cercare solo i documenti di un determinato tribunale.

I filtri proprietà utilizzano un oggetto PropertyFilter. Puoi avere più di un filtro proprietà. Quando utilizzi più filtri proprietà, questi vengono combinati utilizzando l'operatore OR. Un filtro proprietà è definito come segue:

  {
    "documentSchemaName": string,
    "condition": string
  }

Le proprietà sono definite negli schemi. Pertanto, il campo documentSchemaName è quello in cui specifichi lo schema per la proprietà che utilizzi per il filtraggio. Nel campo condition specifichi la logica desiderata. Per esempi di utilizzo dei campi documentSchemaName e condition, consulta gli esempi precedenti in questa pagina.

Documento corrispondente

Un documento corrispondente contiene un Document e uno snippet (di cui parleremo più avanti). Il documento restituito in MatchingDocument non è un documento completamente compilato. Contiene dati minimi per visualizzare un elenco di risultati di ricerca per l'utente che ha effettuato la richiesta. Se è necessario il documento completo (ad esempio, se l'utente ha fatto clic su un risultato di ricerca), il documento completo deve essere recuperato tramite l'API GetDocument.

Vengono compilati i seguenti campi Document: Project number, Document id, Document schema id, Create time, Update time, Display name, Raw document file type, Reference id e Filterable properties.

Un documento corrispondente sarà simile al seguente:

{
  "document": {
    object (Document)
  },
  "searchTextSnippet": string,
  "qaResult": {
    object (QAResult)
  }
}

Classificazione/ordinamento

La richiesta di ricerca ti consente di specificare come vuoi ordinare i risultati. Per ordinare, utilizza il campo order_by nella richiesta di ricerca. I valori possibili per questo campo includono:

  • relevance desc - pertinenza in ordine decrescente, ovvero le corrispondenze migliori sono in alto.
  • upload_date desc - la data di creazione del documento in ordine decrescente (il più recente in alto).
  • upload_date - la data di creazione del documento in ordine crescente (il più vecchio in alto).
  • update_date desc - la data dell'ultimo aggiornamento del documento in ordine decrescente (il più recente in alto).
  • Update_date - la data dell'ultimo aggiornamento del documento in ordine crescente (il più vecchio in alto).

Se non specifichi un ordinamento, ma fornisci parole chiave di ricerca, l'ordinamento avviene in base alla pertinenza in ordine decrescente (le corrispondenze migliori in alto). Se non vengono forniti né l'ordinamento né le parole chiave, l'ordinamento predefinito avviene in base alla data di aggiornamento in ordine decrescente (i documenti più recenti in alto).

Impaginazione

L'impaginazione è utile per mostrare all'utente finale una pagina di dati. Qui puoi specificare le dimensioni della pagina e ottenere un conteggio totale delle dimensioni dei risultati da visualizzare all'utente (ad esempio, "Visualizzazione di 50 documenti su 300").

Imposta il campo page_size sul numero di risultati che vuoi ricevere con la richiesta di ricerca. Questo potrebbe corrispondere ai requisiti delle dimensioni di visualizzazione dei risultati di ricerca dell'interfaccia utente.

Esistono due meccanismi: offset e token di pagina.

Un offset è l'indice nell'elenco dei documenti restituibili che vuoi restituire. Ad esempio, un offset di 5 significa che vuoi il sesto documento in poi. Presumibilmente incrementeresti l'offset in base alle dimensioni della pagina per la pagina successiva di risultati.

In alternativa, puoi utilizzare un token di pagina e non dovrai preoccuparti di calcolare l'offset successivo. Dopo aver effettuato la prima richiesta di ricerca, riceverai una risposta di ricerca contenente il campo next_page_token. Se questo campo è vuoto, non ci sono altri risultati. Se il campo non è vuoto, utilizza questo token nella richiesta di ricerca successiva impostando il campo page_token.

Alcune interfacce utente mostrano il conteggio dei documenti trovati dalla ricerca. Ad esempio, you are viewing 10 documents of 120. Per ottenere un conteggio dei documenti restituiti, imposta il campo require_total_size boolean della richiesta su True. Suggerimento: require_total_size=True comporta una penalizzazione del rendimento. Imposta questo valore nella query della prima pagina, quindi impostalo su false in tutte le richieste successive, mantenendo il conteggio totale in una variabile locale.

Esempi di codice

Python

Per saperne di più, consulta la documentazione di riferimento dell'API Document AI Warehouse Python.

Per eseguire l'autenticazione in Document AI Warehouse, configura le credenziali predefinite dell'applicazione. Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.


from google.cloud import contentwarehouse

# TODO(developer): Uncomment these variables before running the sample.
# project_number = 'YOUR_PROJECT_NUMBER'
# location = 'YOUR_PROJECT_LOCATION' # Format is 'us' or 'eu'
# document_query_text = 'YOUR_DOCUMENT_QUERY'
# user_id = 'user:YOUR_SERVICE_ACCOUNT_ID' # Format is "user:xxxx@example.com"


def search_documents_sample(
    project_number: str, location: str, document_query_text: str, user_id: str
) -> None:
    # Create a client
    client = contentwarehouse.DocumentServiceClient()

    # The full resource name of the location, e.g.:
    # projects/{project_number}/locations/{location}
    parent = client.common_location_path(project=project_number, location=location)

    # File Type Filter
    # Options: DOCUMENT, FOLDER
    file_type_filter = contentwarehouse.FileTypeFilter(
        file_type=contentwarehouse.FileTypeFilter.FileType.DOCUMENT
    )

    # Document Text Query
    document_query = contentwarehouse.DocumentQuery(
        query=document_query_text,
        file_type_filter=file_type_filter,
    )

    # Histogram Query
    histogram_query = contentwarehouse.HistogramQuery(
        histogram_query='count("DocumentSchemaId")'
    )

    request_metadata = contentwarehouse.RequestMetadata(
        user_info=contentwarehouse.UserInfo(id=user_id)
    )

    # Define request
    request = contentwarehouse.SearchDocumentsRequest(
        parent=parent,
        request_metadata=request_metadata,
        document_query=document_query,
        histogram_queries=[histogram_query],
    )

    # Make the request
    response = client.search_documents(request=request)

    # Print search results
    for matching_document in response.matching_documents:
        document = matching_document.document
        # Display name - schema display name.
        # Name.
        # Create date.
        # Snippet - keywords are highlighted with <b> & </b>.
        print(
            f"{document.display_name} - {document.document_schema_name}\n"
            f"{document.name}\n"
            f"{document.create_time}\n"
            f"{matching_document.search_text_snippet}\n"
        )

    # Print histogram
    for histogram_query_result in response.histogram_query_results:
        print(
            f"Histogram Query: {histogram_query_result.histogram_query}\n"
            f"| {'Schema':<70} | {'Count':<15} |"
        )
        for key, value in histogram_query_result.histogram.items():
            print(f"| {key:<70} | {value:<15} |")

Java

Per saperne di più, consulta la Documentazione di riferimento dell'Java API di Document AI Warehouse.

Per eseguire l'autenticazione in Document AI Warehouse, configura le credenziali predefinite dell'applicazione. Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

import com.google.cloud.contentwarehouse.v1.DocumentQuery;
import com.google.cloud.contentwarehouse.v1.DocumentServiceClient;
import com.google.cloud.contentwarehouse.v1.DocumentServiceClient.SearchDocumentsPagedResponse;
import com.google.cloud.contentwarehouse.v1.DocumentServiceSettings;
import com.google.cloud.contentwarehouse.v1.FileTypeFilter;
import com.google.cloud.contentwarehouse.v1.FileTypeFilter.FileType;
import com.google.cloud.contentwarehouse.v1.LocationName;
import com.google.cloud.contentwarehouse.v1.RequestMetadata;
import com.google.cloud.contentwarehouse.v1.SearchDocumentsRequest;
import com.google.cloud.contentwarehouse.v1.SearchDocumentsResponse.MatchingDocument;
import com.google.cloud.contentwarehouse.v1.UserInfo;
import com.google.cloud.resourcemanager.v3.Project;
import com.google.cloud.resourcemanager.v3.ProjectName;
import com.google.cloud.resourcemanager.v3.ProjectsClient;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

public class SearchDocuments {
  public static void main(String[] args) throws IOException, 
        InterruptedException, ExecutionException, TimeoutException { 
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-project-id";
    String location = "your-region"; // Format is "us" or "eu".
    String documentQuery = "your-document-query";
    String userId = "your-user-id"; // Format is user:<user-id>

    searchDocuments(projectId, location, documentQuery, userId);
  }

  // Searches all documents for a given Document Query
  public static void searchDocuments(String projectId, String location,
        String documentQuery, String userId) throws IOException, InterruptedException,
          ExecutionException, TimeoutException { 
    String projectNumber = getProjectNumber(projectId);

    String endpoint = "contentwarehouse.googleapis.com:443";
    if (!"us".equals(location)) {
      endpoint = String.format("%s-%s", location, endpoint);
    }

    DocumentServiceSettings documentServiceSettings = 
             DocumentServiceSettings.newBuilder().setEndpoint(endpoint)
             .build(); 

    /*
     * Create the Document Service Client 
     * Initialize client that will be used to send requests. 
     * This client only needs to be created once, and can be reused for multiple requests. 
     */
    try (DocumentServiceClient documentServiceClient = 
            DocumentServiceClient.create(documentServiceSettings)) {  

      /*
       * The full resource name of the location, e.g.:
       * projects/{project_number}/locations/{location} 
       */
      String parent = LocationName.format(projectNumber, location);

      // Define RequestMetadata object for context of the user making the API call