Поделиться через


Процесс запроса в Поиске Windows

Этот раздел организован следующим образом:

Запросы в поиске Windows основаны на следующих четырех подходах:

AQS — это синтаксис запросов по умолчанию, используемый поиском Windows для запроса индекса и уточнения и узких параметров поиска. AQS в основном ориентирован на пользователей и может использоваться ими для создания запросов в AQS, но также может использоваться разработчиками для создания программных запросов. В Windows 7 был представлен канонический AQS и должен использоваться для программного создания запросов AQS. В Windows 7 и более поздних версиях может быть доступен параметр контекстного меню в зависимости от того, выполнено ли условие AQS. Дополнительные сведения см. в статье "Получение динамического поведения для статических глаголов с помощью расширенного синтаксиса запросов" в Создание обработчиков контекстного меню. Запросы AQS могут быть ограничены определенными типами файлов, которые называются типами файлов. Дополнительные сведения см. в типах файлов и их соответствиях. Справочную документацию по соответствующим свойствам можно найти в System.Kindи System.KindText.

NQS — это синтаксис запросов, который более расслаблен, чем AQS, и похож на человеческий язык. NQS можно использовать в Службе поиска Windows для запроса индекса, если NQS выбран вместо значения по умолчанию, AQS.

SQL — это текстовый язык, определяющий запросы. SQL распространен во многих различных технологиях базы данных. Поиск Windows использует SQL, реализует его подмножество и расширяет язык, добавляя новые элементы. Windows Search SQL расширяет стандартный синтаксис запросов к базе данных SQL-92 и SQL-99, чтобы повысить полезность поиска по тексту. Все функции поиска Windows SQL совместимы с Windows Search в Windows XP, Windows Server 2003 и более поздние версии. Дополнительные сведения о SQL Windows Search см. в запросе индекса с использованием синтаксиса SQL Windows Searchи обзоре синтаксиса SQL Windows Search.

Интерфейсы API структурированных запросов описаны далее в этом разделе. Для получения справочной документации по API структурированных запросов см. Интерфейсы запросов. Интерфейсы, такие как ISearchQueryHelper помогают создавать строки SQL из набора входных значений. Этот интерфейс преобразует запросы пользователей AQS в SQL поиска Windows и задает ограничения запросов, которые могут быть выражены в SQL, но не в AQS. ISearchQueryHelper также получает строку подключения OLE DB для подключения к базе данных Поиска Windows.

Локальные и удаленные запросы

Запросы можно выполнять локально или удаленно. Локальный запрос, использующий предложение FROM , показан в следующем примере. Локальный запрос запрашивает только локальный каталог SystemIndex.

FROM SystemIndex

Удаленный запрос с использованием предложения FROM показан в следующем примере. Добавление ComputerName преобразует предыдущий пример в удаленный запрос.

FROM [<ComputerName>.]SystemIndex

По умолчанию Windows XP и Windows Server 2003 не имеют установленной функции поиска Windows. Только Windows Search 4 (WS4) обеспечивает поддержку удаленных запросов. Предыдущие версии поиска на рабочем столе Windows (WDS), например 3.01 и более ранних версий, не поддерживают удаленные запросы. В проводнике Windows можно запросить локальный индекс удаленного компьютера для элементов файловой системы (элементы, обрабатываемые протоколом file:).

Чтобы получить элемент по удаленному запросу, элемент должен соответствовать следующим требованиям:

  • Быть доступным через UNC-путь.
  • Существует на удаленном компьютере, к которому имеется доступ клиента.
  • Настройте его параметры безопасности, чтобы клиенту был предоставлен доступ для чтения.

В проводнике Windows есть функции для общего доступа к элементам, включая общий ресурс (\\Machine\Public\...) в Центре сети и общего доступа , а также общий ресурс "Пользователи" (\\Machine\Users\...) для элементов, предоставленных через мастер общего доступа. После совместного использования папок можно запросить локальный индекс, указав имя компьютера удаленного компьютера в предложении FROM и UNC-путь на удаленном компьютере в предложении SCOPE. Удаленный запрос с помощью предложений FROM и SCOPE показан в следующем примере.

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

В примерах, приведенных здесь, используется SQL.

Общие сведения об API структурированных запросов

Структурированный запрос обеспечивает возможность поиска информации логическими сочетаниями запросов по отдельным свойствам. В этом разделе описаны функциональные возможности наиболее важных структурированных API-интерфейсов и методов запросов. См. справочную документацию по API структурированных запросов в разделах и.

IQueryParser

Метод IQueryParser::Parse анализирует строку ввода пользователя и создает интерпретацию в виде IQuerySolution. Если параметр pCustomProperties этого метода не имеет значения NULL, то это перечисление объектов IRichChunk (по одному для каждого распознанного пользовательского свойства). Другие методы IQueryParser позволяют приложению задать несколько параметров, таких как языковой стандарт, схема, средство разбиения слов и обработчики для различных типов именованных сущностей. IQueryParser::GetSchemaProvider возвращает интерфейс ISchemaProvider для просмотра загруженной схемы.

IQuerySolution : IConditionFactory

Интерфейс IQuerySolution предоставляет все сведения о результате анализа входной строки. Так как IQuerySolution также является интерфейсом IConditionFactory, можно создать дополнительные узлы дерева условий. Метод IQuerySolution::GetQuery создает дерево условий для интерпретации. IQuerySolution::GetQuery также возвращает семантический тип.

IConditionFactory

IConditionFactory создает узлы дерева условий. Если параметр метода IConditionFactory::MakeNot равен VARIANT_TRUE, то результирующий ICondition упрощается и может не быть узлом отрицания. Если параметр pSubConditionsIConditionFactory::MakeAndOr не имеет значения NULL, то этот параметр должен быть перечислением объектов ICondition и стать поддеревыми.IConditionFactory::MakeLeaf создает конечный узел с указанным именем свойства, операцией и значением. Строка в параметре pValueType должна быть именем семантического типа схемы. Если развернуть параметрVARIANT_TRUE и свойство является виртуальным, результирующее дерево условий обычно является дисъюнкцией, полученной из-за расширения свойства до определенных компонентов. Если значение не равно null, параметры pPropertyNameTerm, pOperatorTermи pValueTerm должны определять термины, указывающие на свойство, операцию и значение.

ICondition: IPersistStream

Интерфейс ICondition является одним узлом в дереве условий. Узел может быть узлом отрицания, узлом И, узлом ИЛИ или конечным узлом. Для неконечного узла ICondition::GetSubConditions возвращает перечисление поддерев. Для конечного узла следующие методы ICondition возвращают следующие значения:

  • GetComparisonInfo возвращает имя свойства, операцию и значение.
  • GetValueType возвращает семантический тип значения, который был указан в параметре pszValueTypeIConditionFactory::MakeLeaf.
  • GetValueNormalization возвращает строковую форму значения. (Если значение уже было строкой, эта форма будет нормализована в отношении регистра, акцентов и т. д.)
  • GetInputTerms возвращает сведения о том, какие части входного предложения создали имя свойства, операцию и значение.
  • Клон возвращает глубокую копию дерева условий.

IRichChunk

Каждый объект IRichChunk определяет диапазон токенов и строку. IRichChunk — это служебный интерфейс, представляющий сведения о диапазоне (обычно диапазон маркеров), определяемый начальной позицией и длиной. Эта информация включает строку и /или VARIANT.

IConditionGenerator

ИнтерфейсIConditionGeneratorпредоставляется приложением для обработки распознавания и создания дерева условий для именованного типа сущности. Генератор условий предоставляется IQueryParser через IQueryParser::SetMultiOption. вызовы IQueryParser IConditionGenerator::Initialize с ISchemaProvider для загруженной схемы. Это позволяет IConditionGenerator получить все необходимые сведения о схеме. При анализе входной строки IQueryParser вызывает метод IConditionGenerator::RecognizeNamedEntities каждого IConditionGenerator, чтобы можно было сообщить о возникновении именованных сущностей, распознаемых в входной строке. IQueryParser может использовать текущий языковой стандарт и должен использовать токенизацию входных данных, так как необходимо сообщать о диапазонах токенов любых именованных сущностей.

Когда IQueryParser собирается выдавать конечный узел, и семантический тип значения соответствует типу именованной сущности для IConditionGenerator, IQueryParser вызывает IConditionGenerator::GenerateforLeaf с информацией для создаваемого узла. Если IConditionGenerator возвращает S_OK, он должен вернуть дерево условий (которое не обязательно должно быть конечным узлом) и сообщить IQueryParser, стоит ли подавлять альтернативную строковую интерпретацию, которую он обычно создает в качестве меры предосторожности.

ITokenCollection

Метод ITokenCollection::NumberOfTokens возвращает количество маркеров.ITokenCollection::GetToken возвращает сведения о токене ith. Начало и длина — это позиции символов в входной строке. Возвращаемый текст не является null только в том случае, если текст заменяет символы из входной строки. Это используется, например, чтобы заменить дефис во входной строке на НЕ, когда этот дефис находится в контексте, где он должен быть истолкован как отрицание.

INamedEntityCollector

IConditionGenerator вызывает INamedEntityCollector::Add для каждой распознанной именованной сущности. Диапазоны — это диапазоны токенов. Это всегда должно быть так, что ? beginActual<endActual ? endSpan. beginSpan и endSpan могут отличаться от beginActual и endActual, если именованная сущность начинается и/или заканчивается семантически незначительными маркерами, такими как кавычки (которые, тем не менее, входят в именованную сущность). Значение должно быть выражено как строка и впоследствии появится в вызове IConditionGenerator::GenerateForLeaf.

ISchemaProvider

ИнтерфейсISchemaProviderможно использовать для просмотра загруженной схемы для сущностей (типов) и связей (свойств). Вот что делают отдельные методы:

  • Сущности возвращает перечисление всех сущностей (IEntity) в схеме.
  • RootEntity возвращает корневую сущность схемы. Для плоской схемы возвращается основной тип каждого IQuerySolution.
  • GetEntity находит сущность по имени и возвращает S_FALSE, если в схеме нет такой сущности.
  • MetaData возвращает перечисление интерфейсов IMetaData.

IEntity

Интерфейс IEntity — это сущность схемы, представляющая тип, имеющий имя, имеет ряд именованных связей с другими типами (свойствами) и производным от базовой сущности. Вот что делают отдельные методы:

  • IEntity::Relationships возвращает перечисление объектов IRelationship, по одному для каждого исходящего отношения данного типа. Каждое исходящее отношение сущности имеет имя.
  • IEntity::GetRelationship находит связь по имени и возвращает S_FALSE, если для этой сущности нет такой связи.
  • IEntity::MetaData возвращает перечисление интерфейсов интерфейсов IMetaData, по одному для каждой пары метаданных этой сущности.
  • IEntity::DefaultPhrase возвращает фразу по умолчанию, чтобы упростить создание повторного утверждения AQS или NQS для дерева условий.

IRelationship

Интерфейс IRelationship представляет связь между двумя сущностями: источником и приемником. Вот что делают отдельные методы:

  • IRelationship::IsReal сообщает, является ли связь реальной. Например, если сущность A является производным от сущности B и наследует от нее связь с именем R, A может по-прежнему иметь собственную связь с именем R. Однако связь beween A и R должна иметь тот же тип назначения, что и тип B, и единственная причина ее существования заключается в хранении метаданных, относящихся к B. Такая связь B, как говорят, не является реальной.
  • IRelationship::Medadata возвращает перечисление интерфейсов IMetaData, по одному для каждой пары метаданных этой сущности.
  • IRelationship::DefaultPhrase возвращает фразу по умолчанию, используемую для этой связи в переформулировках. Каждое отношение имеет фразу по умолчанию, обозначающую это, что упрощает создание переформулировки AQS или NQS дерева условий.

IMetaData

Метаданные — это пары "ключ-значение", которые связаны с сущностью, связью или всей схемой. Так как ключи не обязательно уникальны, коллекция метаданных может рассматриваться как мультикарта. вызывается IMetaData::GetData, чтобы получить ключ и значение для пары метаданных.

Сценарии запросов

В следующих сценариях описано использование API структурированных запросов в Службе поиска Windows в распространенных сценариях запроса, таких как создание дерева условий и запрос индекса.

Извлечение условий и анализ запросов

При создании запроса его область определяется путем указания системе, где искать. Это ограничивает результаты поиска. После определения области применяется фильтр и возвращается набор фильтров. Результаты поиска ограничиваются за счет построения дерева условий с конечными узлами, подобно графу. Затем эти условия извлекаются. Дерево условий — это логическое сочетание (AND, OR, NOT) условий-листьев, каждое из которых связывает свойство с помощью операции со значением. Конечный узел представляет ограничение на одно свойство до значения через некоторые операции.

Для ограничения фильтра требуется логическое выражение, описывающее ограничение. Определение этого выражения начинается с интерфейса ICondition, который используется для создания одного узла в дереве условий. Так как в следующем примере существует только одно условие, дерево не изменяется.

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


Если существует несколько условий фильтра, то для достижения одного дерева используются операторы И и другие логические операторы. И-деревья и ИЛИ-деревья представляют соединения и дизъюнкции их поддеревьев. Дерево NOT-tree представляет собой отрицание своего единственного поддерева. AQS предоставляет текстовый подход к созданию логических выражений с логическими операторами, что часто проще.

В следующем примере мы преобразуем дерево условий (ICondition) в визуальную форму. Средство синтаксического анализа запросов с помощью интерфейса IQueryParser преобразует ICondition в строку запроса с форматированным текстом (RTF). Метод IQueryParser::RestateToString возвращает текст запроса, а метод IQueryParser::Parse создает интерфейс IQuerySolution. В следующем примере показано, как это сделать.

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

Основным входным данными IQueryParser::Parse является строка ввода пользователя для анализа, но приложение также может сообщить средству синтаксического анализа запросов о любых свойствах, которые оно распознало во входных данных (из синтаксиса для конкретного приложения). Выходные данные IQueryParser::Parse — это IQuerySolution, которая предоставляет все сведения, относящиеся к этому вызову парсинга. Существуют методы для получения входной строки, ее токенизации, любых ошибок при синтаксическом анализе, а также разобранного запроса в виде дерева условий, представленного как ICondition. В следующем примере показано ...

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

    

В предыдущем примере IQuerySolution::GetQuery может получить любую информацию о запросе, включая исходный текст, маркеры, составляющие текст или дерево условий. Примеры возможных возвращаемых значений запроса перечислены в следующей таблице.

Примеры возвращаемых значений запроса Описание
author:relja OR author:tyler Текст запроса, который возвращает IQueryParser::RestateToString
?author?, ?:?, ?relja?, ?OR?, ?author?, ?:?, ?tyler? Разбивка токенов
неразрешенное дерево условий Дерево нерешенных условий

 

Исходное дерево условий, возвращаемое, неразрешимо. В дереве неразрешенных условий ссылки на дату и время, такие как date:yesterday, не преобразуются в абсолютное время. Кроме того, виртуальные свойства не развернуты. Виртуальные свойства — это свойства, которые служат агрегатами нескольких свойств.

Например, запрос kind:email from:reljai создает следующие неразрешенные и разрешенные деревья условий. Дерево неразрешенных условий находится слева, и разрешенное дерево условий находится справа.

нерешенные и решенные деревья состояния

Разрешенное дерево можно получить путем вызова IConditionFactory::Resolve. Однако передача SQRO_DONT_RESOLVE_DATETIME приводит к тому, что дата и время остаются неразрешёнными. Есть преимущества для неразрешенного дерева условий, так как дерево неразрешенных условий содержит сведения о запросе. Каждый конечный узел указывает на токены, возвращаемые IQuerySolution::GetLexicalData, которые соответствуют свойству, оператору и значению при использовании интерфейса IRichChunk. В следующем примере показано ...

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

Запрос индекса

Существует несколько подходов к запросу индекса. Некоторые основаны на SQL, а другие основаны на AQS. Кроме того, индекс поиска Windows можно запрашивать программным способом с помощью интерфейсов запросов. Существует три интерфейса, относящиеся к запросу индекса: ISearchQueryHelper, IRowsetPrioritizationи IRowsetEvents. Для концептуальной информации см. раздел Запрос индекса программно.

Вы можете разработать компонент или вспомогательный класс для запроса индекса с помощью интерфейса ISearchQueryHelper. Этот интерфейс реализуется как вспомогательный класс для ISearchCatalogManagerISearchCatalogManager2) и получается путем вызова ISearchCatalogManager::GetQueryHelper. Общие сведения см. в разделе Запрос индекса с помощью ISearchQueryHelper.

ISearchQueryHelper позволяет вам:

  • Получите строку подключения OLE DB для подключения к базе данных Поиска Windows.
  • Преобразуйте запросы пользователей AQS в SQL поиска Windows.
  • Укажите ограничения запросов, которые могут быть выражены в SQL, но не в AQS.

Индексирование событий приоритета и набора строк поддерживается в Windows 7 и более поздних версиях. При использовании IRowsetPrioritization существует стек приоритетов, позволяющий клиенту запрашивать, что области, используемые в конкретном запросе, получаются выше обычного приоритета. IRowsetEvents предоставляет уведомление об изменениях элементов в наборах строк, включая добавление новых элементов, удаление элементов и изменение данных элемента. Использование уведомлений о событиях набора строк гарантирует, что результаты для существующих запросов максимально актуальны. Общие сведения см. в разделе Индексирование приоритетов и событий набора строк в Windows 7.

Индексирование, запросы и уведомления в Windows Search

Что входит в индекс

процесс индексирования в Поиске Windows

Процесс уведомлений в поиске Windows

требования к форматированию URL-адресов