Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cette rubrique est organisée comme suit :
- À propos de l’interrogation dans Windows Search
- Scénarios de requêtes
- rubriques connexes
À propos de l’interrogation dans Windows Search
L’interrogation dans Windows Search est basée sur les quatre approches suivantes :
- Syntaxe de requête avancée (AQS)
- Syntaxe de requête naturelle (NQS)
- Langage de requête structurée (SQL)
- Interfaces de requête structurées
AQS est la syntaxe de requête par défaut utilisée par Windows Search pour interroger l’index et affiner les paramètres de recherche. AQS est principalement accessible aux utilisateurs et peut être utilisé par les utilisateurs pour générer 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. 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 menus contextuels. 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 une documentation de référence sur les propriétés pertinentes, consultez System.Kind et System.KindText.
NQS est une syntaxe de requête plus détendue que la fonction AQS, et est similaire au langage humain. NQS peut être utilisé par Windows Search 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 des requêtes. SQL est courant dans de nombreuses technologies de base de données différentes. Windows Search utilise SQL, implémente un sous-ensemble de celui-ci et l’étend en ajoutant des éléments au langage. Windows Search 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 basées sur du texte. 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 Interroger l’index avec la syntaxe SQL de Recherche Windows et vue d’ensemble de la syntaxe SQL de Recherche Windows.
Les API de requête structurées sont décrites plus loin dans cette rubrique. Pour obtenir de la documentation de référence sur les API de requête structurées, consultez Interfaces d’interrogation. Les interfaces telles que ISearchQueryHelper aident à 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 une requête distante.
FROM [<ComputerName>.]SystemIndex
Par défaut, Windows XP et Windows Server 2003 n’ont pas installé Windows Search. Windows Search 4 (WS4) fournit uniquement la prise en charge des requêtes à distance. Les versions précédentes de Windows Desktop Search (WDS), telles que la version 3.01 et les versions antérieures, ne prennent pas en charge l’interrogation à distance. Avec l’Explorateur Windows, 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.
- Configurer les paramètres de sécurité pour autoriser le client à avoir un accès en lecture.
L’Explorateur Windows propose des fonctionnalités de partage d’éléments, notamment un partage « Public » (\\Machine\Public\...) dans le Centre de partage et de réseau, et un partage « Utilisateurs » (\\Machine\Users\...) pour les éléments partagés via l’Assistant Partage. Après avoir partagé le ou 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 des 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ées les plus importantes. Pour obtenir de la documentation de référence sur les API de requête structurées, consultez Interfaces d’interrogation.
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 les paramètres régionaux, un schéma, un analyseur de mots 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é que IQuerySolution est également une interface IConditionFactory , des nœuds d’arborescence de conditions 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 conditions. Si le paramètre de simplification 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 du paramètre pValueType doit être le nom d’un type sémantique à partir du schéma. Si le paramètre de développement est VARIANT_TRUE et que la propriété est virtuelle, l’arborescence de condition résultante est généralement une disjonction résultant du développement de la propriété à ses constituants définis. S’il n’est 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. Il peut s’agir d’un nœud de négation, d’un nœud AND, d’un nœud OR ou d’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 en profondeur 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. Cette information d'étendue inclut 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 des conditions 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 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’elle 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 afin de signaler les plages de jetons de toutes les entités nommées.
Lorsque 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, IQueryParser appelle IConditionGenerator ::GenerateforLeaf avec les informations du nœud à générer. Si IConditionGenerator retourne S_OK, il doit retourner une arborescence de 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’elle générerait normalement comme précaution.
ITokenCollection
La méthode ITokenCollection ::NumberOfTokens retourne le nombre de jetons. ITokenCollection ::GetToken retourne des informations sur le jeton ith. Le début et la longueur sont des positions de caractères dans la chaîne d’entrée. Le texte retourné ne sera pas nul uniquement s'il existe un texte remplaçant 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’elle a reconnue. Les étendues sont des étendues de jeton. Il doit toujours être vrai que 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 insignifiants tels que des guillemets (qui sont néanmoins couverts par l’entité nommée). La valeur doit être exprimée sous forme de 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 principal de chaque IQuerySolution est retourné.
- GetEntity recherche une entité par nom et retourne S_FALSE s’il n’existe aucune entité de ce type dans le schéma.
- MetaData retourne une énumération des 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 ::Relations retourne une énumération des objets IRelationship , une pour chaque relation sortante de ce type. Chaque relation sortante d’une entité a un nom.
- IEntity ::GetRelationship trouve 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 des interfaces IMetaData , une pour chaque paire de métadonnées de cette entité.
- IEntity::DefaultPhrase retourne une phrase par défaut pour faciliter la reformulation 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-être encore 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 il existe est de stocker des métadonnées spécifiques à B. Une telle relation de B est dite ne pas être réelle.
- IRelationship ::Medadata retourne une énumération des 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 restatéments. Chaque relation a une expression par défaut qui la désigne pour faciliter la génération d’une reformulation AQS ou NQS d’une arborescence conditionnelle.
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 multiple. IMetaData ::GetData est appelé pour récupérer la clé et la valeur d’une paire metatdata.
Scénarios de requêtes
Les scénarios suivants décrivent l’utilisation d’API de requête structurées dans Windows Search 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ù effectuer une recherche. 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 en créant une arborescence de conditions avec des nœuds feuilles, similaire à un graphe. Ces conditions sont ensuite extraites. Un arbre de conditions est une combinaison booléenne (ET, OU, NON) de conditions feuilles, chacune d'entre elles qui relie une propriété, à travers une opération, à une valeur. Un nœud feuille représente une restriction sur une propriété unique pour une valeur à travers quelques 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 arborescence unique. Les arbres AND et OR représentent des conjonctions et des disjonctions de leurs sous-arbres. Un arbre NOT représente la négation de son unique sous-arbre. AQS fournit une approche de texte permettant d’obtenir des expressions logiques avec des opérateurs booléens et est souvent plus simple.
Dans l’exemple suivant, nous convertissons l’arborescence de 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 effectuer tout cela.
[
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 principale 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’elle a reconnues dans l’entrée (à partir de la syntaxe spécifique à l’application). La sortie de IQueryParser::Parse est une IQuerySolution, qui fournit toutes les informations relatives à cette invocation 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, toutes les erreurs d’analyse et la requête analysée en tant qu’arborescence de conditions, représentée par un 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 peut obtenir des informations sur la requête, y compris 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 | Descriptif |
|---|---|
author:relja OR author:tyler |
Texte de requête retourné par IQueryParser ::RestateToString |
?author?, ?:?, ?relja?, ?OR?, ?author?, ?:?, ?tyler? |
Décomposition des jetons |
|
Un arbre de condition non résolu |
L’arborescence de condition initiale retournée reste non 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 est à gauche, et l’arborescence de condition résolue est à droite.
L’arborescence résolue peut être obtenue en appelant IConditionFactory ::Resolve. Toutefois, l'utilisation de SQRO_DONT_RESOLVE_DATETIME laisse la date et l’heure non résolues. Il existe des avantages pour une arborescence de conditions non résolue, car une arborescence de conditions non résolue contient des informations sur la requête. Chaque nœud feuille pointe vers les jetons retournés par IQuerySolution::GetLexicalData, qui sont équivalents à 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 sont basés sur AQS. Vous pouvez également interroger l’index Windows Search 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 Interroger l’index par programmation.
Vous pouvez développer une classe de composant ou 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 Interroger 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 des requêtes utilisateur AQS en SQL pour Recherche Windows.
- Spécifiez les restrictions de requête qui peuvent être exprimées dans SQL, mais pas dans AQS.
L'indexation des priorités et les événements d'ensemble de lignes 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 événements de hiérarchisation et d’ensemble de lignes dans Windows 7.
Rubriques connexes