Processo di query in Windows Search

Questo argomento è organizzato come segue:

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

  • Sintassi di query avanzata (AQS)
  • Sintassi di query naturali (NQS)
  • Structured Query Language (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 altre informazioni, vedere "Getting Dynamic Behavior for Static Verbs by Using Advanced Query Syntax" in Creating Context Menu Handlers .For more information, see "Getting Dynamic Behavior for Static Verbs by Using Advanced Query Syntax" in Creating Context Menu Handlers.For more information, see "Getting Dynamic Behavior for Static Verbs by Using Advanced Query Syntax" in Creating Context Menu Handlers. 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.Kind e System.KindText.

NQS è una sintassi di query più rilassata rispetto a AQS ed è simile al linguaggio umano. NQS può essere usato da Windows Search per eseguire una query sull'indice se NQS è selezionato invece del 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 Esecuzione di query sull'indice con la sintassi SQL di Windows Search e 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 .For reference documentation on the structured query APIs, see Querying Interfaces. Interfacce come ISearchQueryHelper consentono di costruire stringhe SQL da un set di valori di input. Questa interfaccia converte le query utente AQS in SQL di Windows Search e specifica le 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 query locale esegue una query solo sul catalogo SystemIndex locale.

FROM SystemIndex

Nell'esempio seguente viene illustrata una query remota che usa la clausola FROM . 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 risorse è possibile eseguire una query sull'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 la sicurezza per consentire al client di avere accesso in lettura.

Esplora risorse include funzionalità per la condivisione di elementi, tra cui una condivisione "Pubblica" (\\Machine\Public\...) nel Centro 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 Query strutturata

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 .For reference documentation on the structured query APIs, see Querying Interfaces.

IQueryParser

Il metodo IQueryParser::P arse analizza una stringa di input dell'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). Gli altri 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 esplorare lo schema caricato.

IQuerySolution : IConditionFactory

L'interfaccia IQuerySolution fornisce tutte le informazioni sul risultato dell'analisi di una stringa di input. Poiché IQuerySolution è anche un'interfaccia IConditionFactory , è possibile creare nodi dell'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 parametro di semplificazione di IConditionFactory::MakeNot è VARIANT_TRUE, la ICondition risultante viene semplificata 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, un'operazione e un valore di proprietà specificati. La stringa nel parametro pValueType deve essere il nome di un tipo semantico dello schema. Se il parametro di espansione è VARIANT_TRUE e la proprietà è virtuale, l'albero delle condizioni risultante è in genere una disgiunzione risultante dall'espansione della proprietà ai componenti definiti. Se non null, i parametri pPropertyNameTerm, pOperatorTerm e pValueTerm devono identificare i termini che indicano 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:

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 iniziale e una lunghezza. Queste informazioni sull'intervallo includono una stringa e/o un valore VARIANT.

IConditionGenerator

L'interfaccia IConditionGenerator viene fornita dall'applicazione per gestire il riconoscimento e la generazione dell'albero delle condizioni per un tipo di entità denominato. Un generatore di condizioni viene assegnato a un IQueryParser tramite IQueryParser::SetMultiOption. IQueryParser chiama IConditionGenerator::Initialize con un ISchemaProvider per lo schema attualmente caricato. In questo modo , IConditionGenerator può ottenere tutte 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 perché 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 IConditionGenerator restituisce S_OK, deve restituire un albero delle condizioni (che non deve essere un nodo foglia) e informare IQueryParser se eliminare l'interpretazione alternativa della stringa che normalmente verrebbe generata 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 sostituisce i caratteri della 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 ogni entità denominata riconosciuta. Gli intervalli sono intervalli di token. Deve essere sempre il caso 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 le entità (tipi) e le relazioni (proprietà). Ecco cosa fanno i singoli metodi:

  • Le entità restituiscono 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 non esiste tale entità nello schema.
  • MetaData restituisce un'enumerazione delle interfacce IMetaData .

IEntity

L'interfaccia IEntity è 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:

IRelationship

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

  • IRelationship::IsReal indica 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 deve avere lo stesso tipo di destinazione di B e l'unico motivo per cui esiste è archiviare i metadati specifici di B. Tale relazione di B si dice non essere reale.
  • IRelationship::Medadata restituisce un'enumerazione delle interfacce IMetaData , una per ogni coppia di metadati di questa entità.
  • IRelationship::D efaultPhrase restituisce la frase predefinita da usare per questa relazione nei riformulazioni. 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. IMetaData::GetData viene chiamato per recuperare la chiave e il valore per una coppia metatdata.

Scenari di query

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, il relativo 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, simili 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 per 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'interfaccia ICondition , 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 è presente più di una condizione di filtro, vengono usati 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 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 ICondition in una stringa di query rtf formattata (RTF). Il metodo IQueryParser::RestateToString restituisce il testo della query, mentre il metodo IQueryParser::P arse produce un'interfaccia IQuerySolution . Nell'esempio seguente viene illustrato come eseguire questa operazione.

    [
        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::P arse è un IQuerySolution, che fornisce tutte le informazioni relative a tale chiamata di analisi. Esistono metodi per ottenere la stringa di input, il modo in cui la stringa di input è stata tokenizzata, 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, tra cui il testo originale, i token che comprendono 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 Testo della query restituito da IQueryParser::RestateToString
?author?, ?:?, ?relja?, ?OR?, ?author?, ?:?, ?tyler? L'interruzione dei token
un albero delle condizioni non risolto Albero delle condizioni non risolte

 

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 ora assoluta. 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 gli alberi delle condizioni non risolti e risolti seguenti. L'albero delle condizioni non risolte si trova a sinistra e l'albero delle condizioni risolto si trova a destra.

alberi delle condizioni non risolti e risolti

L'albero risolto può essere ottenuto chiamando IConditionFactory::Resolve. Tuttavia, il passaggio di SQRO_DONT_RESOLVE_DATETIME lascia la data e l'ora non risolte. Un albero delle condizioni non risolto presenta vantaggi, 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 usa 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 l'esecuzione di query sull'indice. Alcuni sono basati su SQL e altri sono basati su AQS. È anche possibile eseguire query sull'indice di Windows Search a livello di codice usando le interfacce di query. Esistono tre interfacce specifiche per l'esecuzione di query sull'indice: ISearchQueryHelper, IRowsetPrioritization e IRowsetEvents. Per informazioni concettuali, vedere Esecuzione di query sull'indice a livello di codice.

È possibile sviluppare un componente o una classe helper per eseguire query sull'indice usando l'interfaccia ISearchQueryHelper . Questa interfaccia viene implementata come classe helper per ISearchCatalogManager (e ISearchCatalogManager2) e viene ottenuta chiamando ISearchCatalogManager::GetQueryHelper. Per informazioni concettuali, vedere 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 Windows Search SQL.
  • Specificare le restrizioni di query che possono essere espresse in SQL ma non in AQS.

L'indicizzazione delle priorità e gli eventi del set di righe sono supportati in Windows 7 e versioni successive. Con IRowsetPrioritization è presente uno stack di priorità che consente al client di richiedere che gli ambiti usati in una determinata query vengano assegnati con priorità superiore alla normale. IRowsetEvents fornisce una notifica delle modifiche 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 delle priorità e eventi del set di righe in Windows 7.

Indicizzazione, query e notifiche in Windows Search

Che cos'è incluso nell'indice

Processo di indicizzazione in Windows Search

Processo di notifiche in Windows Search

Requisiti di formattazione DEGLI URL