Condividi tramite


Processo di interrogazione in Windows Search

Questo argomento è organizzato come segue:

L'esecuzione di query in Windows Search si basa sui quattro approcci seguenti:

  • sintassi delle query avanzata (AQS)
  • Sintassi di Query Naturale (NQS)
  • Linguaggio di Query Strutturato (SQL)
  • Interfacce di query strutturate

AQS è la sintassi di query predefinita usata da Windows Search per eseguire query sull'indice e per perfezionare e restringere i parametri di ricerca. AQS è destinato principalmente all'utente e può essere usato dagli utenti per compilare query AQS, ma può anche essere usato dagli sviluppatori per compilare query a livello di codice. In Windows 7, è stato introdotto il servizio AQS canonico e deve essere usato per generare query AQS a livello di codice. In Windows 7 e versioni successive, un'opzione di menu di scelta rapida può essere disponibile in base al fatto che venga soddisfatta una condizione AQS. Per ulteriori informazioni, consultare "Ottenere il comportamento dinamico per verbi statici utilizzando la sintassi avanzata delle query" in Creare i gestori dei menu contestuali. Le query AQS possono essere limitate a tipi specifici di file, noti come tipi di file. Per altre informazioni, vedere tipi di file e associazioni. Per la documentazione di riferimento sulle proprietà pertinenti, vedere System.Kinde System.KindText.

NQS è una sintassi di query più rilassata rispetto a AQS ed è simile al linguaggio umano. È possibile usare NQS da Windows Search per eseguire query sull'indice se è selezionato NQS anziché il valore predefinito, AQS.

SQL è un linguaggio di testo che definisce le query. SQL è comune in molte tecnologie di database diverse. Windows Search usa SQL, implementa un sottoinsieme e lo estende aggiungendo elementi al linguaggio. Windows Search SQL estende la sintassi di query di database SQL-92 e SQL-99 standard per migliorarne l'utilità con le ricerche basate su testo. Tutte le funzionalità di Windows Search SQL sono compatibili con Windows Search in Windows XP e Windows Server 2003 e versioni successive. Per altre informazioni su SQL di Windows Search, vedere Eseguire query sull'indice con sintassi SQL di Windows Searche Panoramica della sintassi SQL di Windows Search.

Le API di query strutturate sono descritte più avanti in questo argomento. Per la documentazione di riferimento sulle API di query strutturate, vedere Querying Interfaces. Interfacce come ISearchQueryHelper aiutare a costruire stringhe SQL da un set di valori di input. Questa interfaccia converte le query utente di AQS in SQL di Windows Search e specifica restrizioni di query che possono essere espresse in SQL ma non in AQS. ISearchQueryHelper ottiene anche una stringa di connessione OLE DB per connettersi al database di Windows Search.

Query locali e remote

È possibile eseguire le query in locale o in remoto. Nell'esempio seguente viene illustrata una query locale che usa la clausola FROM. Una interrogazione locale interroga solo il catalogo SystemIndex locale.

FROM SystemIndex

Una query remota che usa la clausola FROM è illustrata nell'esempio seguente. L'aggiunta di ComputerName trasforma l'esempio precedente in una query remota.

FROM [<ComputerName>.]SystemIndex

Per impostazione predefinita, Windows XP e Windows Server 2003 non dispongono di Windows Search installato. Solo Windows Search 4 (WS4) offre supporto per le query remote. Le versioni precedenti di Windows Desktop Search (WDS), ad esempio 3.01 e versioni precedenti, non supportano l'esecuzione di query remote. Con Esplora file, puoi interrogare l'indice locale di un computer remoto per gli elementi del file system (elementi gestiti dal protocollo 'file:').

Per recuperare un elemento tramite query remota, l'elemento deve soddisfare i requisiti seguenti:

  • Essere accessibile tramite il percorso UNC (Universal Naming Convention).
  • Esiste nel computer remoto a cui il client ha accesso.
  • Impostare le impostazioni di sicurezza per consentire al client l'accesso in lettura.

Esplora file include funzionalità per la condivisione di elementi, tra cui una condivisione "Pubblica" (\\Machine\Public\...) nel Centro Connessioni di rete e condivisione e una condivisione "Utenti" (\\Machine\Users\...) per gli elementi condivisi tramite la Condivisione Guidata. Dopo aver condiviso le cartelle, è possibile eseguire una query sull'indice locale specificando il nome del computer remoto nella clausola FROM e un percorso UNC nel computer remoto nella clausola SCOPE. Nell'esempio seguente viene illustrata una query remota che usa le clausole FROM e SCOPE.

SELECT System.ItemName FROM MachineName.SystemIndex WHERE SCOPE='file://MachineName/<path>' 

Gli esempi forniti qui usano SQL.

Panoramica dell'API Structured Query

Una query strutturata consente di cercare informazioni in base a combinazioni booleane di query su singole proprietà. In questo argomento vengono illustrate le funzionalità delle API e dei metodi di query strutturati più importanti. Per la documentazione di riferimento sulle API di query strutturate, vedere Querying Interfaces.

IQueryParser

Il metodo IQueryParser::Parse analizza una stringa di input utente e produce un'interpretazione sotto forma di IQuerySolution. Se il parametro pCustomProperties di tale metodo non è Null, è un'enumerazione di oggetti IRichChunk(uno per ogni proprietà personalizzata riconosciuta). Le altre metodi IQueryParser consentono all'applicazione di impostare diverse opzioni, ad esempio impostazioni locali, uno schema, un word breaker e gestori per vari tipi di entità denominate. IQueryParser::GetSchemaProvider restituisce un'interfaccia ISchemaProvider per l'esplorazione dello schema caricato.

IQuerySolution : IConditionFactory

L'interfacciaIQuerySolutionfornisce tutte le informazioni sul risultato dell'analisi di una stringa di input. Poiché IQuerySolution è anche un'interfaccia IConditionFactory, è possibile creare nodi di albero delle condizioni aggiuntivi. Il metodo IQuerySolution::GetQuery produce un albero delle condizioni per l'interpretazione. IQuerySolution::GetQuery restituisce anche il tipo semantico.

IConditionFactory

IConditionFactory crea nodi dell'albero delle condizioni. Se il semplificare parametro di IConditionFactory::MakeNot è VARIANT_TRUE, ilICondition risultanteè semplificato e non deve essere un nodo di negazione. Se il parametro pSubConditions di IConditionFactory::MakeAndOr non è Null, tale parametro deve essere un'enumerazione di oggetti ICondition e diventare sottoalberi.IConditionFactory::MakeLeaf costruisce un nodo foglia con un nome di proprietà, un'operazione e un valore specificati. La stringa nel parametro pValueType deve essere il nome di un tipo semantico dallo schema. Se il parametro espandi è VARIANT_TRUE e la proprietà è virtuale, l'albero delle condizioni risultante è solitamente una disgiunzione risultante dall'espansione della proprietà ai componenti definiti. Se non null, i parametri pPropertyNameTerm, pOperatorTerme pValueTerm devono identificare i termini indicanti la proprietà, l'operazione e il valore.

ICondition : IPersistStream

L'interfaccia ICondition è un singolo nodo in un albero delle condizioni. Il nodo può essere un nodo di negazione, un nodo AND, un nodo OR o un nodo foglia. Per un nodo non foglia ICondition::GetSubConditions restituisce un'enumerazione dei sottoalberi. Per un nodo foglia, i metodi seguenti di ICondition restituiscono i valori seguenti:

  • getComparisonInfo restituisce il nome, l'operazione e il valore della proprietà.
  • GetValueType restituisce il tipo semantico del valore, specifico nel parametro pszValueType di IConditionFactory::MakeLeaf.
  • GetValueNormalization restituisce una forma stringa del valore. Se il valore era già una stringa, questa forma verrà normalizzata in relazione a maiuscole e minuscole, accenti e così via.
  • GetInputTerms restituisce informazioni sulle parti della frase di input che hanno generato il nome della proprietà, l'operazione e il valore.
  • Clone restituisce una copia completa di un albero delle condizioni.

IRichChunk

Ogni oggetto IRichChunk identifica un intervallo di token e una stringa. IRichChunk è un'interfaccia di utilità che rappresenta informazioni su un intervallo (in genere un intervallo di token) identificato da una posizione e una lunghezza iniziali. Queste informazioni sull'intervallo includono una stringa e/o un VARIANT.

IConditionGenerator

L'interfacciaIConditionGeneratorviene fornita dall'applicazione per gestire la generazione di albero di riconoscimento e condizione per un tipo di entità denominato. Un generatore di condizioni viene dato a un IQueryParser tramite IQueryParser::SetMultiOption. IQueryParser chiama IConditionGenerator::Initialize con un ISchemaProvider per lo schema attualmente caricato. In questo modo è possibile IConditionGenerator ottenere le informazioni sullo schema necessarie. Quando si analizza una stringa di input, IQueryParser chiama il metodo IConditionGenerator::RecognizeNamedEntities di ogni IConditionGenerator, in modo che sia possibile segnalare l'occorrenza delle entità denominate riconosciute nella stringa di input. IQueryParser può usare le impostazioni locali correnti e deve usare la tokenizzazione dell'input in quanto deve segnalare gli intervalli di token di qualsiasi entità denominata.

Quando IQueryParser sta per generare un nodo foglia e il tipo semantico del valore corrisponde al tipo di entità denominato per un IConditionGenerator, IQueryParser chiama IConditionGenerator::GenerateforLeaf con le informazioni per il nodo da generare. Se il IConditionGenerator restituisce S_OK, dovrebbe restituire un albero delle condizioni (che non deve essere un nodo foglia) e informare IQueryParser se eliminare l'interpretazione alternativa della stringa che normalmente genererebbe come precauzione.

ITokenCollection

Il metodo ITokenCollection::NumberOfTokens restituisce il numero di token.ITokenCollection::GetToken restituisce informazioni sul token i. L'inizio e la lunghezza sono posizioni di caratteri nella stringa di input. Il testo restituito sarà diverso da Null solo se è presente un testo che esegue l'override dei caratteri dalla stringa di input. Viene usato, ad esempio, per eseguire l'override di un trattino nella stringa di input con NOT quando tale trattino si trova in un contesto in cui deve essere interpretato come negazione.

INamedEntityCollector

IConditionGenerator chiama INamedEntityCollector::Add per ciascuna entità denominata che riconosce. Gli intervalli sono intervalli di token. È sempre necessario che beginSpan ? beginActual<endActual ? endSpan. beginSpan e endSpan possono differire da beginActual e endActual se l'entità denominata inizia e/o termina con token semanticamente insignificanti, ad esempio virgolette (che sono comunque coperti dall'entità denominata). Il valore deve essere espresso come stringa e verrà successivamente visualizzato in una chiamata a IConditionGenerator::GenerateForLeaf.

ISchemaProvider

L'interfaccia ISchemaProvider può essere usata per esplorare uno schema caricato per entità (tipi) e relazioni (proprietà). Ecco cosa fanno i singoli metodi:

  • Entities restituisce un'enumerazione di ogni entità (IEntity) nello schema.
  • rootEntity restituisce l'entità radice dello schema. Per uno schema flat, viene restituito il tipo principale di ogni IQuerySolution.
  • GetEntity trova un'entità in base al nome e restituisce S_FALSE se tale entità non è presente nello schema.
  • MetaData restituisce un'enumerazione delle interfacceIMetaData.

IEntity

L'interfacciaIEntityè un'entità dello schema che rappresenta un tipo con un nome, ha una serie di relazioni denominate con altri tipi (proprietà) e deriva da un'entità di base. Ecco cosa fanno i singoli metodi:

  • IEntity::Relationships restituisce un'enumerazione di oggettiIRelationship, uno per ogni relazione in uscita di questo tipo. Ogni relazione in uscita di un'entità ha un nome.
  • IEntity::GetRelationship trova una relazione in base al nome e restituisce S_FALSE se non esiste una relazione di questo tipo per questa entità.
  • IEntity::MetaData restituisce un'enumerazione delle interfacceIMetaData, una per ogni coppia di metadati di questa entità.
  • IEntity::DefaultPhrase restituisce una frase predefinita per facilitare la generazione di una riformulazione AQS o NQS di un albero delle condizioni.

IRelationship

L'interfacciaIRelationshiprappresenta una relazione tra due entità: un'origine e una destinazione. Ecco cosa fanno i singoli metodi:

  • IRelationship::IsReal segnala se una relazione è reale. Ad esempio, se l'entità A deriva dall'entità B e eredita una relazione denominata R da essa, A potrebbe comunque avere una propria relazione denominata R. Tuttavia, la relazione beween A e R deve avere lo stesso tipo di destinazione di quello di B e l'unico motivo per cui esiste è archiviare i metadati specifici di B. Tale relazione di B si dice di non essere reale.
  • IRelationship::Medadata restituisce un'enumerazione di interfacce IMetaData, una per ogni coppia di metadati di questa entità.
  • IRelationship::DefaultPhrase restituisce la frase predefinita da usare per questa relazione in riformazioni. Ogni relazione ha una frase predefinita che lo indica per facilitare la generazione di una rivalutazione AQS o NQS di un albero delle condizioni.

IMetaData

I metadati sono coppie chiave-valore associate a un'entità, a una relazione o all'intero schema. Poiché le chiavi non sono necessariamente univoche, una raccolta di metadati può essere considerata come una mappa multipla. viene chiamato IMetaData::GetData per recuperare la chiave e il valore per una coppia metadati.

Scenari di interrogazione

Gli scenari seguenti descrivono l'uso di API di query strutturate in Windows Search in scenari di query comuni, ad esempio la creazione di un albero delle condizioni e l'esecuzione di query sull'indice.

Estrazione delle condizioni e analisi delle query

Quando viene creata una query, l'ambito viene definito indicando al sistema dove eseguire la ricerca. Ciò limita i risultati della ricerca. Dopo aver definito l'ambito, viene applicato un filtro e viene restituito un set di filtri. I risultati della ricerca sono limitati creando un albero delle condizioni con nodi foglia, simile a un grafico. Tali condizioni vengono quindi estratte. Un albero delle condizioni è una combinazione booleana (AND, OR, NOT) di condizioni foglia, ognuna delle quali correla una proprietà, tramite un'operazione, a un valore. Un nodo foglia rappresenta una restrizione di una singola proprietà a un valore tramite alcune operazioni.

Una restrizione di filtro richiede un'espressione logica che descrive la restrizione. La definizione di questa espressione inizia con l'interfacciaICondition, usata per creare un singolo nodo in un albero delle condizioni. Poiché nell'esempio seguente è presente una sola condizione, l'albero non cambia.

    
    [
        object,
        uuid(0FC988D4-C935-4b97-A973-46282EA175C8),
        pointer_default(unique)
    ]
    interface ICondition : IPersistStream
    {
        HRESULT GetConditionType([out, retval] CONDITION_TYPE* pNodeType);
        HRESULT GetSubConditions([in] REFIID riid, [out, retval, iid_is(riid)] void** ppv);
        [local] HRESULT GetComparisonInfo([out, annotation("__deref_opt_out")] LPWSTR *ppszPropertyName, [out, annotation("__out_opt")] CONDITION_OPERATION *pOperation, [out, annotation("__out_opt")] PROPVARIANT *pValue);
        HRESULT GetValueType([out, retval] LPWSTR* ppszValueTypeName);
        HRESULT GetValueNormalization([out, retval] LPWSTR* ppszNormalization);
        [local] HRESULT GetInputTerms([out, annotation("__out_opt")] IRichChunk** ppPropertyTerm, [out, annotation("__out_opt")] IRichChunk** ppOperationTerm, [out, annotation("__out_opt")] IRichChunk** ppValueTerm);
        HRESULT Clone([out, retval] ICondition** ppc);
    };


Se sono presenti più condizioni di filtro, vengono usati gli operatori AND e altri operatori booleani per ottenere un singolo albero. Gli alberi AND e gli alberi OR rappresentano congiunzioni e disgiunzioni dei relativi sottoalberi. Un albero NOT rappresenta la negazione del relativo singolo sottoalbero. AQS offre un approccio testuale per ottenere espressioni logiche con operatori booleani ed è spesso più semplice.

Nell'esempio seguente viene convertito l'albero delle condizioni (ICondition) in formato visivo. Il parser di query, usando l'interfaccia IQueryParser, converte il ICondition in una stringa di query in formato RTF (rich text format). Il metodo IQueryParser::RestateToString restituisce il testo della query, mentre il metodo IQueryParser::Parse produce un'interfaccia IQuerySolution. Nell'esempio seguente viene illustrato come eseguire tutte queste operazioni.

    [
        object,
        uuid(2EBDEE67-3505-43f8-9946-EA44ABC8E5B0),
        pointer_default(unique)
    ]
    interface IQueryParser : IUnknown
    {
        HRESULT Parse([in] LPCWSTR pszInputString, [in] IEnumUnknown* pCustomProperties, [out, retval] IQuerySolution** ppSolution);
        HRESULT SetOption([in] STRUCTURED_QUERY_SINGLE_OPTION option, [in] PROPVARIANT const* pOptionValue);
        HRESULT GetOption([in] STRUCTURED_QUERY_SINGLE_OPTION option, [out, retval] PROPVARIANT* pOptionValue);
        HRESULT SetMultiOption([in] STRUCTURED_QUERY_MULTIOPTION option, [in] LPCWSTR pszOptionKey, [in] PROPVARIANT const* pOptionValue);
        HRESULT GetSchemaProvider([out, retval] ISchemaProvider** ppSchemaProvider);
        HRESULT RestateToString([in] ICondition* pCondition, [in] BOOL fUseEnglish, [out] LPWSTR* ppszQueryString);
        HRESULT ParsePropertyValue([in] LPCWSTR pszPropertyName, [in] LPCWSTR pszInputString, [out, retval] IQuerySolution** ppSolution);
        HRESULT RestatePropertyValueToString([in] ICondition* pCondition, [in] BOOL fUseEnglish, [out] LPWSTR* ppszPropertyName, [out] LPWSTR* ppszQueryString);
    };

L'input principale di IQueryParser::P arse è una stringa di input utente da analizzare, ma l'applicazione può anche informare il parser di query di tutte le proprietà riconosciute nell'input (dalla sintassi specifica dell'applicazione). L'output di IQueryParser::Parse è un IQuerySolution, che fornisce tutte le informazioni relative a tale invocazione di parsing. Sono disponibili metodi per ottenere la stringa di input, il modo in cui la stringa di input è stata tokenizzata, gli eventuali errori di analisi e la query analizzata come albero delle condizioni, rappresentata da un ICondition. L'esempio seguente mostra ...

    [
        object,
        uuid(D6EBC66B-8921-4193-AFDD-A1789FB7FF57),
        pointer_default(unique)
    ]
    interface IQuerySolution : IConditionFactory
    {
        [local] HRESULT GetQuery([out, annotation("__out_opt")] ICondition** ppQueryNode, [out, annotation("__out_opt")] IEntity** ppMainType);
        HRESULT GetErrors([in] REFIID riid, [out, retval, iid_is(riid)] void** ppParseErrors);
        [local] HRESULT GetLexicalData([out, annotation("__deref_opt_out")] LPWSTR* ppszInputString, [out, annotation("__out_opt")] ITokenCollection** ppTokens, [out, annotation("__out_opt")] LCID* pLocale, [out, annotation("__out_opt")] IUnknown** ppWordBreaker);
    }    

    

Nell'esempio precedente IQuerySolution::GetQuery potrebbe ottenere informazioni sulla query, inclusi il testo originale, i token che costituiscono il testo o l'albero delle condizioni. Nella tabella seguente sono elencati esempi di possibili valori di query restituiti.

Esempi di valori di query restituiti Descrizione
author:relja OR author:tyler Il testo della query che IQueryParser::RestateToString restituisce
?author?, ?:?, ?relja?, ?OR?, ?author?, ?:?, ?tyler? La scomposizione dei token
un albero delle condizioni non risolto Albero delle condizioni irrisolte

 

L'albero delle condizioni iniziale restituito non è risolto. In un albero delle condizioni non risolto, i riferimenti di data e ora, ad esempio date:yesterday, non vengono convertiti in tempo assoluto. Inoltre, le proprietà virtuali non vengono espanse. Le proprietà virtuali sono proprietà che fungono da aggregazioni di più proprietà.

Ad esempio, la query kind:email from:reljai produce i seguenti alberi delle condizioni: non risolti e risolti. L'albero delle condizioni non risolto si trova a sinistra e l'albero delle condizioni risolte si trova a destra.

alberi delle condizioni risolte e non risolte

È possibile ottenere l'albero risolto chiamando IConditionFactory::Resolve. Tuttavia, il passaggio di SQRO_DONT_RESOLVE_DATETIME lascia la data e l'ora non risolte. Esistono vantaggi per un albero delle condizioni non risolto, perché un albero delle condizioni non risolto contiene informazioni sulla query. Ogni nodo foglia punta ai token restituiti da IQuerySolution::GetLexicalData, che corrispondono alla proprietà, all'operatore e al valore quando si utilizza l'interfaccia IRichChunk. L'esempio seguente mostra ...

    interface ITokenCollection : IUnknown
    {
        HRESULT NumberOfTokens(ULONG* pCount);
        HRESULT GetToken([in] ULONG i, [out, annotation("__out_opt")] ULONG* pBegin, [out, annotation("__out_opt")] ULONG* pLength, [out, annotation("__deref_opt_out")] LPWSTR* ppsz);
    };

ICondition:: GetInputTerms([out, annotation("__out_opt")] 
IRichChunk** ppPropertyTerm, [out, annotation("__out_opt")] 
IRichChunk** ppOperationTerm, [out, annotation("__out_opt")] 
IRichChunk** ppValueTerm);

    interface IRichChunk : IUnknown
    {
        HRESULT GetData([out, annotation("__out_opt")] ULONG* pFirstPos, [out, annotation("__out_opt")] ULONG* pLength, [out, annotation("__deref_opt_out")] LPWSTR* ppsz, [out, annotation("__out_opt")] PROPVARIANT* pValue);
    }

Esecuzione di query sull'indice

Esistono diversi approcci per eseguire query sull'indice. Alcuni sono basati su SQL e altri si basano su AQS. È anche possibile eseguire query sull'indice di Windows Search a livello di codice usando interfacce di query. Esistono tre interfacce specifiche per l'esecuzione di query sull'indice: ISearchQueryHelper, IRowsetPrioritizatione IRowsetEvents. Per informazioni concettuali, vedere l'esecuzione di query sull'indice a livello di codice.

È possibile sviluppare un componente o una classe helper per eseguire query sull'indice usando l'interfacciaISearchQueryHelper. Questa interfaccia viene implementata come classe helper per ISearchCatalogManager (e ISearchCatalogManager2) e viene ottenuta chiamando ISearchCatalogManager::GetQueryHelper. Per informazioni concettuali, vedere l'esecuzione di query sull'indice con ISearchQueryHelper.

ISearchQueryHelper consente di:

  • Ottenere una stringa di connessione OLE DB per connettersi al database di Windows Search.
  • Convertire le query utente di AQS in SQL di Windows Search.
  • Specificare le restrizioni di query che possono essere espresse in SQL, ma non in AQS.

Gli eventi di indicizzazione e insiemi di righe sono supportati in Windows 7 e versioni successive. Con IRowsetPrioritization esiste uno stack di priorità che consente al client di richiedere che agli ambiti usati in una determinata query venga assegnata una priorità superiore alla normale. IRowsetEvents fornisce notifica delle modifiche apportate agli elementi nei set di righe, tra cui l'aggiunta di nuovi elementi, l'eliminazione di elementi e la modifica dei dati dell'elemento. L'uso delle notifiche degli eventi del set di righe garantisce che i risultati per le query esistenti siano il più aggiornati possibile. Per informazioni concettuali, vedere Indicizzazione prioritaria e eventi dei set di righe in Windows 7.

L'Indicizzazione, l'Esecuzione di Query e le Notifiche in Windows Search

Cosa è incluso nell'indice

processo di indicizzazione in Windows Search

Processo di notifiche in Windows Search

Requisiti di Formattazione URL