Partager via


Processus d’interrogation dans Windows Search

Cette rubrique est organisée comme suit :

L’interrogation dans Recherche Windows est basée sur les quatre approches suivantes :

  • Syntaxe de requête avancée (AQS)
  • Syntaxe de requête naturelle (NQS)
  • SQL (Structured Query Language)
  • Interfaces de requête structurées

AQS est la syntaxe de requête par défaut utilisée par Recherche Windows pour interroger l’index et affiner et affiner les paramètres de recherche. AQS est principalement destiné aux utilisateurs et peut être utilisé par les utilisateurs pour créer des requêtes AQS, mais peut également être utilisé par les développeurs pour générer des requêtes par programmation. Dans Windows 7, AQS canonique a été introduit et doit être utilisé pour générer par programmation des requêtes AQS. Dans Windows 7 et versions ultérieures, une option de menu contextuel peut être disponible selon qu’une condition AQS est remplie ou non. Pour plus d’informations, consultez « Obtention d’un comportement dynamique pour les verbes statiques à l’aide de la syntaxe de requête avancée » dans Création de gestionnaires de menu contextuel. Les requêtes AQS peuvent être limitées à des types spécifiques de fichiers, appelés types de fichiers. Pour plus d’informations, consultez Types de fichiers et associations. Pour obtenir de la documentation de référence sur les propriétés appropriées, consultez System.Kind et System.KindText.

NQS est une syntaxe de requête qui est plus détendue qu’AQS et qui est similaire au langage humain. NQS peut être utilisé par Recherche Windows pour interroger l’index si NQS est sélectionné au lieu de la valeur par défaut, AQS.

SQL est un langage de texte qui définit les requêtes. SQL est courant dans de nombreuses technologies de base de données différentes. Recherche Windows utilise SQL, implémente un sous-ensemble de celui-ci et l’étend en ajoutant des éléments au langage. Recherche Windows SQL étend la syntaxe de requête de base de données SQL-92 et SQL-99 standard pour améliorer son utilité avec les recherches textuelles. Toutes les fonctionnalités de Windows Search SQL sont compatibles avec Windows Search sur Windows XP et Windows Server 2003 et versions ultérieures. Pour plus d’informations sur Windows Search SQL, consultez Interrogation de l’index à l’aide de la syntaxe SQL de Recherche Windows et Vue d’ensemble de la syntaxe SQL de Recherche Windows.

Les API de requête structurée sont décrites plus loin dans cette rubrique. Pour obtenir de la documentation de référence sur les API de requête structurée, consultez Interrogation des interfaces. Des interfaces telles que ISearchQueryHelper permettent de construire des chaînes SQL à partir d’un ensemble de valeurs d’entrée. Cette interface convertit les requêtes utilisateur AQS en SQL Recherche Windows et spécifie les restrictions de requête qui peuvent être exprimées dans SQL, mais pas dans AQS. ISearchQueryHelper obtient également une chaîne de connexion OLE DB pour se connecter à la base de données Windows Search.

Requêtes locales et distantes

Vous pouvez exécuter vos requêtes localement ou à distance. Une requête locale utilisant la clause FROM est illustrée dans l’exemple suivant. Une requête locale interroge uniquement le catalogue SystemIndex local.

FROM SystemIndex

Une requête distante utilisant la clause FROM est illustrée dans l’exemple suivant. L’ajout de ComputerName transforme l’exemple précédent en requête distante.

FROM [<ComputerName>.]SystemIndex

Par défaut, Windows XP et Windows Server 2003 n’ont pas Windows Search installé. Seul Windows Search 4 (WS4) prend en charge les requêtes à distance. Les versions précédentes de Recherche de bureau Windows (WDS), telles que les versions 3.01 et antérieures, ne prennent pas en charge l’interrogation à distance. Avec Windows Explorer vous pouvez interroger l’index local d’un ordinateur distant pour les éléments du système de fichiers (éléments gérés par le protocole « file: »).

Pour récupérer un élément par requête distante, l’élément doit répondre aux exigences suivantes :

  • Être accessible via le chemin d’accès UNC (Universal Naming Convention).
  • Existe sur l’ordinateur distant auquel le client a accès.
  • Avoir sa sécurité définie pour autoriser le client à disposer d’un accès en lecture.

Windows Explorer dispose de fonctionnalités de partage d’éléments, notamment un partage « Public » (\\Machine\Public\...) dans le Centre réseau et partage, et un partage « Utilisateurs » (\\Machine\Users\...) pour les éléments partagés via l’Assistant Partage. Après avoir partagé les dossiers, vous pouvez interroger l’index local en spécifiant le nom de l’ordinateur distant dans la clause FROM et un chemin UNC sur l’ordinateur distant dans la clause SCOPE. Une requête distante utilisant les clauses FROM et SCOPE est illustrée dans l’exemple suivant.

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

Les exemples fournis ici utilisent SQL.

Vue d’ensemble de l’API de requête structurée

Une requête structurée permet de rechercher des informations par combinaisons booléennes de requêtes sur des propriétés individuelles. Dans cette rubrique, nous décrivons les fonctionnalités des api et méthodes de requête structurée les plus importantes. Pour obtenir de la documentation de référence sur les API de requête structurée, consultez Interrogation des interfaces.

IQueryParser

La méthode IQueryParser::P arse analyse une chaîne d’entrée utilisateur et produit une interprétation sous la forme d’une IQuerySolution. Si le paramètre pCustomProperties de cette méthode n’est pas null, il s’agit d’une énumération d’objets IRichChunk (un pour chaque propriété personnalisée reconnue). Les autres méthodes IQueryParser permettent à l’application de définir plusieurs options, telles que des paramètres régionaux, un schéma, un disjoncteur et des gestionnaires pour différents types d’entités nommées. IQueryParser::GetSchemaProvider retourne une interface ISchemaProvider pour parcourir le schéma chargé.

IQuerySolution : IConditionFactory

L’interface IQuerySolution fournit toutes les informations sur le résultat de l’analyse d’une chaîne d’entrée. Étant donné qu’IQuerySolution est également une interface IConditionFactory, des nœuds d’arborescence de condition supplémentaires peuvent être créés. La méthode IQuerySolution::GetQuery produit une arborescence de conditions pour l’interprétation. IQuerySolution::GetQuery retourne également le type sémantique.

IConditionFactory

IConditionFactory crée des nœuds d’arborescence de condition. Si le paramètre simplifie de IConditionFactory::MakeNot est VARIANT_TRUE, l’ICondition résultant est simplifié et n’a pas besoin d’être un nœud de négation. Si le paramètre pSubConditions de IConditionFactory::MakeAndOr n’est pas null, ce paramètre doit être une énumération d’objets ICondition et devenir des sous-arborescences. IConditionFactory::MakeLeaf construit un nœud feuille avec un nom de propriété, une opération et une valeur spécifiés. La chaîne dans le paramètre pValueType doit être le nom d’un type sémantique du schéma. Si le paramètre expand est VARIANT_TRUE et que la propriété est virtuelle, l’arborescence de conditions résultante est généralement une disjonction résultant de l’extension de la propriété à ses composants définis. S’ils ne sont pas null, les paramètres pPropertyNameTerm, pOperatorTerm et pValueTerm doivent identifier les termes indiquant la propriété, l’opération et la valeur.

ICondition : IPersistStream

L’interface ICondition est un nœud unique dans une arborescence de conditions. Le nœud peut être un nœud de négation, un nœud AND, un nœud OR ou un nœud feuille. Pour un nœud non feuille , ICondition::GetSubConditions retourne une énumération des sous-arborescences. Pour un nœud feuille, les méthodes suivantes d’ICondition retournent les valeurs suivantes :

  • GetComparisonInfo retourne le nom de la propriété, l’opération et la valeur.
  • GetValueType retourne le type sémantique de la valeur, qui a été spécifique dans le paramètre pszValueType de IConditionFactory::MakeLeaf.
  • GetValueNormalization retourne une forme de chaîne de la valeur. (Si la valeur était déjà une chaîne, ce formulaire sera normalisé en ce qui concerne la casse, les accents, etc.)
  • GetInputTerms retourne des informations sur les parties de la phrase d’entrée qui ont généré le nom de la propriété, l’opération et la valeur.
  • Clone retourne une copie approfondie d’une arborescence de conditions.

IRichChunk

Chaque objet IRichChunk identifie une étendue de jeton et une chaîne. IRichChunk est une interface utilitaire qui représente des informations sur une étendue (généralement une étendue de jetons) identifiée par une position de départ et une longueur. Ces informations d’étendue incluent une chaîne et/ou un VARIANT.

IConditionGenerator

L’interface IConditionGenerator est fournie par l’application pour gérer la reconnaissance et la génération d’arborescence de condition pour un type d’entité nommé. Un générateur de conditions est donné à un IQueryParser via IQueryParser::SetMultiOption. IQueryParser appelle IConditionGenerator::Initialize avec un ISchemaProvider pour le schéma actuellement chargé. Cela permet à IConditionGenerator d’obtenir toutes les informations de schéma requises. Lors de l’analyse d’une chaîne d’entrée, IQueryParser appelle la méthode IConditionGenerator::RecognizeNamedEntities de chaque IConditionGenerator, afin que l’occurrence d’entités nommées qu’il reconnaît dans la chaîne d’entrée puisse être signalée. IQueryParser peut utiliser les paramètres régionaux actuels et doit utiliser la tokenisation de l’entrée, car il doit signaler les étendues de jetons de toutes les entités nommées.

Quand IQueryParser est sur le point d’émettre un nœud feuille et que le type sémantique de la valeur correspond au type d’entité nommé pour un IConditionGenerator, IQueryParserer appelle IConditionGenerator::GenerateforLeaf avec les informations pour le nœud à générer. Si IConditionGenerator retourne S_OK, il doit retourner une arborescence des conditions (qui n’a pas besoin d’être un nœud feuille) et informer IQueryParser s’il faut supprimer l’interprétation de chaîne alternative qu’il générerait normalement par précaution.

ITokenCollection

La méthode ITokenCollection::NumberOfTokens retourne le nombre de jetons. ITokenCollection::GetToken retourne des informations sur le iième jeton. Le début et la longueur sont des positions de caractères dans la chaîne d’entrée. Le texte retourné n’est pas null uniquement s’il y a un texte qui substitue les caractères de la chaîne d’entrée. Cela est utilisé, par exemple, pour remplacer un tiret dans la chaîne d’entrée par NOT lorsque ce tiret se trouve dans un contexte où il doit être interprété comme une négation.

INamedEntityCollector

IConditionGenerator appelle INamedEntityCollector::Add pour chaque entité nommée qu’il a reconnue. Les étendues sont des étendues de jetons. Il doit toujours être le cas qui beginSpan ? beginActual<endActual ? endSpan. beginSpan et endSpan peuvent différer de beginActual et endActual si l’entité nommée commence et/ou se termine par des jetons sémantiquement non significatifs tels que des guillemets (qui sont néanmoins couverts par l’entité nommée). La valeur doit être exprimée sous la forme d’une chaîne et apparaîtra par la suite dans un appel à IConditionGenerator::GenerateForLeaf.

ISchemaProvider

L’interface ISchemaProvider peut être utilisée pour parcourir un schéma chargé pour les entités (types) et les relations (propriétés). Voici ce que font les méthodes individuelles :

  • Les entités retournent une énumération de chaque entité (IEntity) dans le schéma.
  • RootEntity retourne l’entité racine du schéma. Pour un schéma plat, le type main de chaque IQuerySolution est retourné.
  • GetEntity recherche une entité par son nom et retourne S_FALSE s’il n’y a pas d’entité de ce type dans le schéma.
  • MetaData retourne une énumération d’interfaces IMetaData .

IEntity

L’interface IEntity est une entité de schéma qui représente un type qui a un nom, a un certain nombre de relations nommées avec d’autres types (propriétés) et dérive d’une entité de base. Voici ce que font ses méthodes individuelles :

  • IEntity::Relationships retourne une énumération d’objets IRelationship , un pour chaque relation sortante de ce type. Chaque relation sortante d’une entité a un nom.
  • IEntity::GetRelationship recherche une relation par nom et retourne S_FALSE s’il n’existe aucune relation de ce type pour cette entité.
  • IEntity::MetaData retourne une énumération d’interfaces IMetaData , une pour chaque paire de métadonnées de cette entité.
  • IEntity::D efaultPhrase retourne une expression par défaut pour faciliter la génération d’une restatément AQS ou NQS d’une arborescence de conditions.

IRelationship

L’interface IRelationship représente une relation entre deux entités : une source et une destination. Voici ce que font les méthodes individuelles :

  • IRelationship::IsReal indique si une relation est réelle. Par exemple, si l’entité A dérive de l’entité B et hérite d’une relation nommée R, A peut toujours avoir sa propre relation nommée R. Toutefois, la relation entre A et R doit avoir le même type de destination que celui de B, et la seule raison pour laquelle elle existe est de stocker des métadonnées spécifiques à B. On dit qu’une telle relation de B n’est pas réelle.
  • IRelationship::Medadata retourne une énumération d’interfaces IMetaData , une pour chaque paire de métadonnées de cette entité.
  • IRelationship::D efaultPhrase retourne l’expression par défaut à utiliser pour cette relation dans les restaments. Chaque relation a une expression par défaut qui la désigne pour faciliter la génération d’une reformatément AQS ou NQS d’une arborescence de conditions.

IMetaData

Les métadonnées sont des paires clé-valeur qui sont chacune associées à une entité, une relation ou l’ensemble du schéma. Étant donné que les clés ne sont pas nécessairement uniques, une collection de métadonnées peut être considérée comme une carte multi map. IMetaData::GetData est appelé pour récupérer la clé et la valeur d’une paire metatdata.

Scénarios d’interrogation

Les scénarios suivants décrivent l’utilisation d’API de requête structurée dans Recherche Windows dans des scénarios d’interrogation courants, tels que la création d’une arborescence de conditions et l’interrogation de l’index.

Extraction de condition et analyse des requêtes

Lorsqu’une requête est créée, son étendue est définie en indiquant au système où rechercher. Cela limite les résultats de la recherche. Une fois l’étendue définie, un filtre est appliqué et un jeu de filtres est retourné. Les résultats de la recherche sont limités par la création d’une arborescence de conditions avec des nœuds feuilles, semblable à un graphique. Ces conditions sont ensuite extraites. Une arborescence de conditions est une combinaison booléenne (AND, OR, NOT) de conditions feuilles, chacune d’elles associant une propriété, par le biais d’une opération, à une valeur. Un nœud feuille représente une restriction sur une propriété unique à une valeur par le biais de certaines opérations.

Une restriction de filtre nécessite une expression logique qui décrit la restriction. La définition de cette expression commence par l’interface ICondition , qui est utilisée pour créer un nœud unique dans une arborescence de conditions. Étant donné qu’il n’existe qu’une seule condition dans l’exemple suivant, l’arborescence ne change pas.

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


S’il existe plusieurs conditions de filtre, AND et d’autres opérateurs booléens sont utilisés pour obtenir une seule arborescence. Les arbres AND et OR représentent des conjonctions et des disjonctions de leurs sous-arborescences. Une arborescence NOT représente la négation de sa sous-arborescence unique. AQS fournit une approche textuelle pour obtenir des expressions logiques avec des opérateurs booléens et est souvent plus simple.

Dans l’exemple suivant, nous convertissons l’arborescence des conditions (ICondition) en forme visuelle. L’analyseur de requête, à l’aide de l’interface IQueryParser , convertit l’ICondition en chaîne de requête RTF (Rich Text Formatted). La méthode IQueryParser::RestateToString retourne le texte de la requête, tandis que la méthode IQueryParser::P arse produit une interface IQuerySolution . L’exemple suivant montre comment procéder.

    [
        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’entrée main de IQueryParser::P arse est une chaîne d’entrée utilisateur à analyser, mais l’application peut également informer l’analyseur de requête de toutes les propriétés qu’il a reconnues dans l’entrée (à partir de la syntaxe propre à l’application). La sortie de IQueryParser::P arse est une IQuerySolution, qui fournit toutes les informations relatives à cet appel d’analyse. Il existe des méthodes pour obtenir la chaîne d’entrée, la façon dont la chaîne d’entrée a été tokenisée, les erreurs d’analyse éventuelles et la requête analysée en tant qu’arborescence de condition, représentée par une ICondition. L’exemple suivant montre ...

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

    

Dans l’exemple précédent, IQuerySolution::GetQuery pouvait obtenir des informations sur la requête, notamment le texte d’origine, les jetons qui composent le texte ou l’arborescence des conditions. Les exemples de valeurs de requête retournées possibles sont répertoriés dans le tableau suivant.

Exemples de valeurs de requête retournées Description
author:relja OR author:tyler Texte de requête retourné par IQueryParser::RestateToString
?author?, ?:?, ?relja?, ?OR?, ?author?, ?:?, ?tyler? La casse des jetons
une arborescence de conditions non résolue Arborescence des conditions non résolue

 

L’arborescence de conditions initiale retournée n’est pas résolue. Dans une arborescence de conditions non résolue, les références de date et d’heure, telles que date:yesterday, ne sont pas converties en heure absolue. En outre, les propriétés virtuelles ne sont pas développées. Les propriétés virtuelles sont des propriétés qui agissent comme des agrégats de plusieurs propriétés.

Par exemple, la requête kind:email from:reljai produit les arborescences de conditions non résolues et résolues suivantes. L’arborescence des conditions non résolues se trouve à gauche et l’arborescence des conditions résolues se trouve à droite.

arborescences de conditions non résolues et non résolues

L’arborescence résolue peut être obtenue en appelant IConditionFactory::Resolve. Toutefois, le passage SQRO_DONT_RESOLVE_DATETIME laisse la date et l’heure non résolues. Une arborescence de conditions non résolue présente des avantages, car une arborescence de conditions non résolues contient des informations sur la requête. Chaque nœud feuille pointe vers les jetons retournés par IQuerySolution::GetLexicalData, qui correspondent à la propriété, à l’opérateur et à la valeur lors de l’utilisation de l’interface IRichChunk . L’exemple suivant montre ...

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

Interrogation de l’index

Il existe plusieurs approches pour interroger l’index. Certains sont basés sur sql et d’autres sur AQS. Vous pouvez également interroger l’index Recherche Windows par programmation à l’aide d’interfaces d’interrogation. Il existe trois interfaces spécifiques à l’interrogation de l’index : ISearchQueryHelper, IRowsetPrioritization et IRowsetEvents. Pour plus d’informations conceptuelles, consultez Interrogation de l’index par programmation.

Vous pouvez développer un composant ou une classe d’assistance pour interroger l’index à l’aide de l’interface ISearchQueryHelper . Cette interface est implémentée en tant que classe d’assistance pour ISearchCatalogManager (et ISearchCatalogManager2) et est obtenue en appelant ISearchCatalogManager::GetQueryHelper. Pour plus d’informations conceptuelles, consultez Interrogation de l’index avec ISearchQueryHelper.

ISearchQueryHelper vous permet de :

  • Obtenez une chaîne de connexion OLE DB pour vous connecter à la base de données Windows Search.
  • Convertissez les requêtes utilisateur AQS en Sql Recherche Windows.
  • Spécifiez les restrictions de requête qui peuvent être exprimées dans SQL, mais pas dans AQS.

Les événements de hiérarchisation et d’ensemble de lignes d’indexation sont pris en charge dans Windows 7 et versions ultérieures. Avec IRowsetPrioritization , il existe une pile de priorités qui permet au client de demander que les étendues utilisées dans une requête particulière soient supérieures à la priorité normale. IRowsetEvents fournit une notification des modifications apportées aux éléments dans les ensembles de lignes, notamment l’ajout de nouveaux éléments, la suppression d’éléments et la modification des données d’élément. L’utilisation des notifications d’événements d’ensemble de lignes garantit que les résultats des requêtes existantes sont aussi à jour que possible. Pour plus d’informations conceptuelles, consultez Indexation des priorités et événements d’ensemble de lignes dans Windows 7.

Indexation, interrogation et notifications dans Recherche Windows

Éléments inclus dans l’index

Processus d’indexation dans Recherche Windows

Processus de notifications dans Recherche Windows

Configuration requise pour la mise en forme d’URL