Partilhar via


Processo de consulta na Pesquisa do Windows

Este tópico é organizado da seguinte maneira:

A consulta na Pesquisa do Windows baseia-se nas quatro abordagens a seguir:

O AQS é a sintaxe de consulta padrão usada pelo Windows Search para consultar o índice e refinar e restringir parâmetros de pesquisa. O AQS é voltado principalmente para o usuário e pode ser usado pelos usuários para criar consultas AQS, mas também pode ser usado por desenvolvedores para criar consultas programaticamente. No Windows 7, o AQS canônico foi introduzido e deve ser usado para gerar consultas do AQS programaticamente. No Windows 7 e posteriores, uma opção de menu de atalho pode estar disponível com base em se uma condição do AQS é atendida. Para obter mais informações, confira "Como obter comportamento dinâmico para verbos estáticos usando a sintaxe de consulta avançada" em Criando manipuladores de menu de contexto. As consultas do AQS podem ser limitadas a tipos específicos de arquivos, que são conhecidos como tipos de arquivo. Para obter mais informações, consulte Tipos de arquivo e associações. Para obter a documentação de referência sobre as propriedades relevantes, consulte System.Kind e System.KindText.

O NQS é uma sintaxe de consulta mais relaxada que o AQS e é semelhante à linguagem humana. O NQS pode ser usado pela Pesquisa do Windows para consultar o índice se o NQS estiver selecionado em vez do padrão, o AQS.

SQL é uma linguagem de texto que define consultas. O SQL é comum em várias tecnologias de banco de dados diferentes. O Windows Search usa SQL, implementa um subconjunto dele e o estende adicionando elementos ao idioma. O SQL da Pesquisa do Windows estende a sintaxe de consulta de banco de dados SQL-92 e SQL-99 padrão para aprimorar sua utilidade com pesquisas baseadas em texto. Todos os recursos do SQL de Pesquisa do Windows são compatíveis com a Pesquisa do Windows no Windows XP e no Windows Server 2003 e posteriores. Para obter mais informações sobre o SQL da Pesquisa do Windows, consulte Consultando o índice com a sintaxe do SQL de pesquisa do Windows e Visão geral da sintaxe do SQL da Pesquisa do Windows.

As APIs de consulta estruturadas são descritas posteriormente neste tópico. Para obter a documentação de referência sobre as APIs de consulta estruturadas, consulte Interfaces de consulta. Interfaces como ISearchQueryHelper ajudam a construir cadeias de caracteres SQL de um conjunto de valores de entrada. Essa interface converte consultas de usuário do AQS no SQL de Pesquisa do Windows e especifica restrições de consulta que podem ser expressas no SQL, mas não no AQS. ISearchQueryHelper também obtém uma cadeia de conexão OLE DB para se conectar ao banco de dados do Windows Search.

Consultas locais e remotas

Você pode executar suas consultas local ou remotamente. Uma consulta local usando a cláusula FROM é mostrada no exemplo a seguir. Uma consulta local consulta apenas o catálogo systemIndex local.

FROM SystemIndex

Uma consulta remota usando a cláusula FROM é mostrada no exemplo a seguir. Adicionar ComputerName transforma o exemplo anterior em uma consulta remota.

FROM [<ComputerName>.]SystemIndex

Por padrão, o Windows XP e o Windows Server 2003 não têm o Windows Search instalado. Somente o Windows Search 4 (WS4) fornece suporte a consultas remotas. As versões anteriores da Pesquisa da Área de Trabalho do Windows (WDS), como 3.01 e anteriores, não dão suporte à consulta remota. Com o Windows Explorer você pode consultar o índice local de um computador remoto em busca de itens do sistema de arquivos (itens manipulados pelo protocolo "file:").

Para recuperar um item por consulta remota, o item deve atender aos seguintes requisitos:

  • Seja acessível por meio do caminho UNC (Convenção Universal de Nomenclatura).
  • Existe no computador remoto ao qual o cliente tem acesso.
  • Tenha sua segurança definida para permitir que o cliente tenha acesso de leitura.

O Windows Explorer tem recursos para compartilhar itens, incluindo um compartilhamento "Público" (\\Máquina\Pública\...) no Centro de Rede e Compartilhamento e um compartilhamento "Usuários" (\\Computador\Usuários\...) para itens compartilhados por meio do Assistente de Compartilhamento. Depois de compartilhar as pastas, você pode consultar o índice local especificando o nome do computador remoto na cláusula FROM e um caminho UNC no computador remoto na cláusula SCOPE. Uma consulta remota usando as cláusulas FROM e SCOPE é mostrada no exemplo a seguir.

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

Os exemplos fornecidos aqui usam SQL.

Visão geral da API de Consulta Estruturada

Uma consulta estruturada fornece a capacidade de pesquisar informações por combinações boolianas de consultas em propriedades individuais. Neste tópico, descrevemos a funcionalidade das APIs e métodos de consulta estruturados mais importantes. Para obter a documentação de referência sobre as APIs de consulta estruturadas, consulte Interfaces de consulta.

IQueryParser

O método IQueryParser::P arse analisa uma cadeia de caracteres de entrada do usuário e produz uma interpretação na forma de um IQuerySolution. Se o parâmetro pCustomProperties desse método não for nulo, será uma enumeração de objetos IRichChunk (um para cada propriedade personalizada reconhecida). Os outros métodos IQueryParser permitem que o aplicativo defina várias opções, como localidade, esquema, separador de palavras e manipuladores para vários tipos de entidades nomeadas. IQueryParser::GetSchemaProvider retorna uma interface ISchemaProvider para navegar no esquema carregado.

IQuerySolution : IConditionFactory

A interface IQuerySolution fornece todas as informações sobre o resultado da análise de uma cadeia de caracteres de entrada. Como IQuerySolution também é uma interface IConditionFactory , nós de árvore de condição adicionais podem ser criados. O método IQuerySolution::GetQuery produz uma árvore de condição para a interpretação. IQuerySolution::GetQuery também retorna o tipo semântico.

IConditionFactory

IConditionFactory cria nós de árvore de condição. Se o parâmetro de simplificação de IConditionFactory::MakeNot for VARIANT_TRUE, a ICondition resultante será simplificada e não precisará ser um nó de negação. Se o parâmetro pSubConditions de IConditionFactory::MakeAndOr não for nulo, esse parâmetro deverá ser uma enumeração de objetos ICondition e se tornar subárvores. IConditionFactory::MakeLeaf constrói um nó folha com um nome de propriedade, operação e valor especificados. A cadeia de caracteres no parâmetro pValueType deve ser o nome de um tipo semântico do esquema. Se o parâmetro de expansão for VARIANT_TRUE e a propriedade for virtual, a árvore de condição resultante normalmente será uma disjunção resultante da expansão da propriedade para seus constituintes definidos. Se não for nulo, os parâmetros pPropertyNameTerm, pOperatorTerm e pValueTerm deverão identificar os termos que indicam a propriedade, a operação e o valor.

ICondition : IPersistStream

A interface ICondition é um único nó em uma árvore de condição. O nó pode ser um nó de negação, nó AND, nó OR ou um nó folha. Para um nó não folha ICondition::GetSubConditions retorna uma enumeração das subárvores. Para um nó folha, os seguintes métodos de ICondition retornam os seguintes valores:

  • GetComparisonInfo retorna o nome da propriedade, a operação e o valor.
  • GetValueType retorna o tipo semântico do valor, que foi especificado no parâmetro pszValueType de IConditionFactory::MakeLeaf.
  • GetValueNormalization retorna uma forma de cadeia de caracteres do valor. (Se o valor já era uma cadeia de caracteres, esse formulário será normalizado em relação a maiúsculas e minúsculas e assim por diante.)
  • GetInputTerms retorna informações sobre quais partes da frase de entrada geraram o nome da propriedade, a operação e o valor.
  • Clone retorna uma cópia profunda de uma árvore de condição.

IRichChunk

Cada objeto IRichChunk identifica um intervalo de token e uma cadeia de caracteres. IRichChunk é uma interface de utilitário que representa informações sobre um intervalo (normalmente um intervalo de tokens) identificado por uma posição inicial e comprimento. Essas informações de intervalo incluem uma cadeia de caracteres e/ou uma VARIANT.

IConditionGenerator

A interface IConditionGenerator é fornecida pelo aplicativo para lidar com a geração de árvore de reconhecimento e condição para um tipo de entidade nomeado. Um gerador de condição é dado a um IQueryParser por meio de IQueryParser::SetMultiOption. IQueryParser chama IConditionGenerator::Initialize com um ISchemaProvider para o esquema carregado no momento. Isso permite que IConditionGenerator obtenha todas as informações de esquema necessárias. Ao analisar uma cadeia de caracteres de entrada, IQueryParser chama o método IConditionGenerator::RecognizeNamedEntities de cada IConditionGenerator, para que a ocorrência de entidades nomeadas que ele reconhece na cadeia de caracteres de entrada possa ser relatada. O IQueryParser pode usar a localidade atual e deve usar a tokenização da entrada, pois precisa relatar os intervalos de token de qualquer entidade nomeada.

Quando IQueryParser está prestes a emitir um nó folha e o tipo semântico do valor corresponde ao tipo de entidade nomeada para um IConditionGenerator, IQueryParser chama IConditionGenerator::GenerateforLeaf com as informações para o nó a ser gerado. Se IConditionGenerator retornar S_OK, ele deverá retornar uma árvore de condição (que não precisa ser um nó folha) e informar ao IQueryParser se deve suprimir a interpretação de cadeia de caracteres alternativa que normalmente geraria como precaução.

ITokenCollection

O método ITokenCollection::NumberOfTokens retorna o número de tokens. ITokenCollection::GetToken retorna informações sobre o token ith. O início e o comprimento são posições de caractere na cadeia de caracteres de entrada. O texto retornado será não nulo somente se houver um texto substituindo os caracteres da cadeia de caracteres de entrada. Isso é usado, por exemplo, para substituir um traço na cadeia de caracteres de entrada por NOT quando esse traço está em um contexto em que ele deve ser interpretado como uma negação.

INamedEntityCollector

IConditionGenerator chama INamedEntityCollector::Add para cada entidade nomeada reconhecida. Os intervalos são intervalos de token. Deve ser sempre o caso de beginSpan ? beginActual<endActual? endSpan. beginSpan e endSpan poderão ser diferentes de beginActual e endActual se a entidade nomeada começar e/ou terminar com tokens semanticamente insignificantes, como aspas (que, no entanto, são cobertos pela entidade nomeada). O valor deve ser expresso como uma cadeia de caracteres e aparecerá posteriormente em uma chamada para IConditionGenerator::GenerateForLeaf.

ISchemaProvider

A interface ISchemaProvider pode ser usada para procurar um esquema carregado para entidades (tipos) e relações (propriedades). Veja o que os métodos individuais fazem:

  • Entidades retorna uma enumeração de cada entidade (IEntity) no esquema.
  • RootEntity retorna a entidade raiz do esquema. Para um esquema simples, o tipo main de cada IQuerySolution é retornado.
  • GetEntity localiza uma entidade por nome e retorna S_FALSE se não houver essa entidade no esquema.
  • MetaData retorna uma enumeração de interfaces IMetaData .

IEntity

A interface IEntity é uma entidade de esquema que representa um tipo que tem um nome, tem várias relações nomeadas com outros tipos (propriedades) e deriva de uma entidade base. Veja o que seus métodos individuais fazem:

  • IEntity::Relationships retorna uma enumeração de objetos IRelationship , uma para cada relação de saída desse tipo. Cada relação de saída de uma entidade tem um nome.
  • IEntity::GetRelationship localiza uma relação por nome e retorna S_FALSE se não houver essa relação para essa entidade.
  • IEntity::MetaData retorna uma enumeração de interfaces IMetaData , uma para cada par de metadados dessa entidade.
  • IEntity::D efaultPhrase retorna uma frase padrão para facilitar a geração de uma reformulação do AQS ou NQS de uma árvore de condição.

Irelationship

A interface IRelationship representa uma relação entre duas entidades: uma origem e um destino. Veja o que os métodos individuais fazem:

  • IRelationship::IsReal relata se uma relação é real. Por exemplo, se a entidade A deriva da entidade B e herda uma relação chamada R dela, A ainda poderá ter sua própria relação chamada R. No entanto, a relação entre A e R deve ter o mesmo tipo de destino que o de B, e o único motivo para ela existir é armazenar metadados específicos de B. Diz-se que tal relação de B não é real.
  • IRelationship::Medadata retorna uma enumeração de interfaces IMetaData , uma para cada par de metadados dessa entidade.
  • IRelationship::D efaultPhrase retorna a frase padrão a ser usada para essa relação em declarações. Cada relação tem uma frase padrão que a denota para facilitar a geração de uma reformulação do AQS ou NQS de uma árvore de condição.

IMetaData

Os metadados são pares chave-valor associados a uma entidade, uma relação ou todo o esquema. Como as chaves não são necessariamente exclusivas, uma coleção de metadados pode ser considerada um mapa múltiplo. IMetaData::GetData é chamado para recuperar a chave e o valor de um par metatdata.

Cenários de consulta

Os cenários a seguir descrevem o uso de APIs de consulta estruturadas no Windows Search em cenários comuns de consulta, como criar uma árvore de condição e consultar o índice.

Extração de condições e análise de consulta

Quando uma consulta é criada, seu escopo é definido informando ao sistema onde pesquisar. Isso restringe os resultados da pesquisa. Depois que o escopo é definido, um filtro é aplicado e um conjunto de filtros é retornado. Os resultados da pesquisa são restritos pela criação de uma árvore de condições com nós folha, semelhante a um grafo. Essas condições são então extraídas. Uma árvore de condição é uma combinação booliana (AND, OR, NOT) de condições folha, cada uma das quais relaciona uma propriedade, por meio de uma operação, a um valor. Um nó folha representa uma restrição em uma única propriedade para um valor por meio de algumas operações.

Uma restrição de filtro requer uma expressão lógica que descreve a restrição. Definir essa expressão começa com a interface ICondition , que é usada para criar um único nó em uma árvore de condição. Como há apenas uma condição no exemplo a seguir, a árvore não é alterada.

    
    [
        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 houver mais de uma condição de filtro, AND e outros operadores boolianos serão usados para alcançar uma única árvore. Árvores AND e OR representam conjunções e disjunções de suas subárvores. Uma NOT-tree representa a negação de sua única subárvore. O AQS fornece uma abordagem de texto para alcançar expressões lógicas com operadores boolianos e geralmente é mais simples.

No próximo exemplo, convertemos a árvore de condição (ICondition) em um formulário visual. O analisador de consulta, usando a interface IQueryParser , converte a ICondition em uma cadeia de caracteres de consulta com formato rich text (RTF). O método IQueryParser::RestateToString retorna o texto da consulta, enquanto o método IQueryParser::P arse produz uma interface IQuerySolution . O exemplo a seguir mostra como fazer tudo isso.

    [
        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);
    };

A entrada main de IQueryParser::P arse é uma cadeia de caracteres de entrada do usuário a ser analisada, mas o aplicativo também pode informar o analisador de consulta de todas as propriedades reconhecidas na entrada (da sintaxe específica do aplicativo). A saída de IQueryParser::P arse é uma IQuerySolution, que fornece todas as informações relativas a essa invocação de análise. Há métodos para obter a cadeia de caracteres de entrada, como a cadeia de caracteres de entrada foi tokenizada, quaisquer erros de análise e a consulta analisada como árvore de condição, representada por uma ICondition. O exemplo a seguir 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);
    }    

    

No exemplo anterior, IQuerySolution::GetQuery poderia obter qualquer informação sobre a consulta, incluindo o texto original, tokens que compõem o texto ou a árvore de condição. Exemplos de possíveis valores de consulta retornados estão listados na tabela a seguir.

Exemplos de valores de consulta retornados Descrição
author:relja OR author:tyler O texto da consulta que IQueryParser::RestateToString retorna
?author?, ?:?, ?relja?, ?OR?, ?author?, ?:?, ?tyler? A quebra de tokens
uma árvore de condição não resolvida Uma árvore de condição não resolvida

 

A árvore de condição inicial retornada não está resolvida. Em uma árvore de condição não resolvida, as referências de data e hora, como date:yesterday, não são convertidas em hora absoluta. Além disso, as propriedades virtuais não são expandidas. Propriedades virtuais são propriedades que atuam como agregações de várias propriedades.

Por exemplo, a consulta kind:email from:reljai produz as seguintes árvores de condição não resolvidas e resolvidas. A árvore de condição não resolvida fica à esquerda e a árvore de condição resolvida está à direita.

árvores de condição não resolvidas e resolvidas

A árvore resolvida pode ser obtida chamando IConditionFactory::Resolve. No entanto, passar SQRO_DONT_RESOLVE_DATETIME deixa a data e a hora não resolvidas. Há vantagens em uma árvore de condição não resolvida, pois uma árvore de condição não resolvida contém informações sobre a consulta. Cada nó folha aponta para os tokens retornados por IQuerySolution::GetLexicalData, que correspondem à propriedade, operador e valor ao usar a interface IRichChunk . O exemplo a seguir 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);
    }

Consultando o índice

Há várias abordagens para consultar o índice. Alguns são baseados no SQL e outros são baseados no AQS. Você também pode consultar o índice do Windows Search programaticamente usando interfaces de consulta. Há três interfaces específicas para consultar o índice: ISearchQueryHelper, IRowsetPrioritization e IRowsetEvents. Para obter informações conceituais, consulte Consultando o índice programaticamente.

Você pode desenvolver um componente ou classe auxiliar para consultar o índice usando a interface ISearchQueryHelper . Essa interface é implementada como uma classe auxiliar para ISearchCatalogManager (e ISearchCatalogManager2) e é obtida chamando ISearchCatalogManager::GetQueryHelper. Para obter informações conceituais, consulte Consultando o índice com ISearchQueryHelper.

ISearchQueryHelper permite que você:

  • Obtenha uma cadeia de conexão OLE DB para se conectar ao banco de dados do Windows Search.
  • Converter consultas de usuário do AQS em SQL do Windows Search.
  • Especifique restrições de consulta que podem ser expressas no SQL, mas não no AQS.

Há suporte para a priorização de indexação e eventos de conjunto de linhas no Windows 7 e posterior. Com IRowsetPrioritization , há uma pilha de prioridade que permite ao cliente solicitar que os escopos usados em uma consulta específica recebam prioridade maior que a normal. IRowsetEvents fornece notificação de alterações em itens em conjuntos de linhas, incluindo a adição de novos itens, a exclusão de itens e a modificação de dados de item. O uso de notificações de evento de conjunto de linhas garante que os resultados das consultas existentes estejam o mais atualizados possível. Para obter informações conceituais, consulte Indexando eventos de priorização e conjunto de linhas no Windows 7.

Indexação, consulta e notificações na Pesquisa do Windows

O que está incluído no índice

Processo de indexação no Windows Search

Processo de notificações na Pesquisa do Windows

Requisitos de formatação de URL