本主題的組織方式如下:
關於在 Windows 搜尋中查詢
Windows 搜尋中的查詢是以下列四種方法為基礎:
- 進階查詢語法 (AQS)
- 自然查詢語法 (NQS)
- 結構化查詢語言 (SQL)
- 結構化查詢介面
AQS 是 Windows 搜尋用來查詢索引和精簡搜尋參數的預設查詢語法。 AQS 主要是使用者面向,而且可由使用者用來建置 AQS 查詢,但也可供開發人員以程式設計方式建置查詢。 在 Windows 7 中,引進標準 AQS,而且必須用來以程式設計方式產生 AQS 查詢。 在 Windows 7 和更新版本中,可以根據是否符合 AQS 條件,提供快捷方式功能表選項。 如需詳細資訊,請參閱 建立作功能表處理程式中的「使用進階查詢語法來獲取靜態動詞的動態行為」。 AQS 查詢可以限製為特定類型的檔案,這些檔案稱為檔類型。 如需詳細資訊,請參閱 檔案類型和關聯。 如需相關屬性的參考檔,請參閱 System.Kind和 System.KindText。
NQS 是比 AQS 更寬鬆的查詢語法,類似於人類語言。 如果已選取 NQS,而不是預設的 AQS,則 Windows 搜尋可以使用 NQS 來查詢索引。
SQL 是定義查詢的文字語言。 SQL 在許多不同的資料庫技術中很常見。 Windows 搜尋會使用 SQL、實作它的子集,並將元素新增至語言來擴充它。 Windows 搜尋 SQL 擴充標準 SQL-92 和 SQL-99 資料庫查詢語法,以增強其在以文字為基礎的搜尋的實用性。 Windows Search SQL 的所有功能都與 Windows XP 和 Windows Server 2003 及更新版本的 Windows 搜尋相容。 如需 Windows 搜尋 SQL 的詳細資訊,請參閱 使用 Windows 搜尋 SQL 語法查詢索引和 windows 搜尋 SQL 語法概觀。
本主題稍後會說明結構化查詢 API。 如需結構化查詢 API 的參考檔,請參閱 查詢介面。 ISearchQueryHelper 等介面 協助從一組輸入值建構 SQL 字串。 此介面會將 AQS 使用者查詢轉換成 Windows 搜尋 SQL,並指定可在 SQL 中表示但不能以 AQS 表示的查詢限制。 ISearchQueryHelper 也會取得連線到 Windows 搜尋資料庫的 OLE DB 連接字串。
本機和遠端查詢
您可以在本機或遠端執行查詢。 下列範例顯示使用 FROM 子句的本機查詢。 本機查詢只會查詢本機 SystemIndex 目錄。
FROM SystemIndex
下列範例顯示使用 FROM 子句 的遠端查詢。 新增 ComputerName 會將上述範例轉換成遠端查詢。
FROM [<ComputerName>.]SystemIndex
根據預設,Windows XP 和 Windows Server 2003 未安裝 Windows 搜尋。 只有 Windows 搜尋 4 (WS4) 提供遠端查詢支援。 舊版的 Windows 桌面搜尋 (WDS),例如 3.01 和更早版本,不支援遠端查詢。 使用 Windows 檔案總管,您可以查詢遠端電腦的本地索引,以獲取檔案系統項目(由 "file:" 協議處理的項目)。
若要透過遠端查詢擷取項目,該項目必須符合下列要求:
- 可透過通用命名約定 (UNC) 路徑存取。
- 存在於用戶端可存取的遠端電腦上。
- 將其安全性設定為允許用戶端具有讀取許可權。
Windows 檔案總管具有共享專案的功能,包括 網路及共用中心中的「公共」共用(\\Machine\Public\...),以及透過共用精靈共用之專案的「使用者」共用(\\Machine\Users\...)。 共用資料夾之後,您可以在FROM子句中指定遠端電腦的電腦名稱,以及SCOPE子句中遠端電腦上的 UNC 路徑,以查詢本機索引。 下列範例顯示使用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 會簡化,而且不需要是否定節點。 如果 IConditionFactory::MakeAndOr 的 pSubConditions 參數不是 null,則該參數應該是 ICondition 物件的列舉,並成為子樹。IConditionFactory::MakeLeaf 會建構具有指定屬性名稱、作業和值的分葉節點。 pValueType 參數中的字串應該是架構中語意類型的名稱。 如果 展開 參數是 VARIANT_TRUE 且屬性是虛擬的,則產生的條件樹狀結構通常是從將屬性展開至其已定義之組成項所產生的分離。 如果不是 null,pPropertyNameTerm、pOperatorTerm,以及 pValueTerm 參數應該識別指出屬性、作業和值的字詞。
ICondition : IPersistStream
ICondition 介面是條件樹狀結構中的單一節點。 節點可以是負節點、AND節點、OR節點或分葉節點。 對於非分葉節點 ICondition::GetSubConditions 會傳回子樹的列舉。 如果是分葉節點,ICondition 的下列方法 會傳回下列值:
- GetComparisonInfo 會傳回屬性名稱、作業和值。
- GetValueType 會傳回值的語義類型,該值類型是在 IConditionFactory::MakeLeaf的 pszValueType 參數中指定的。
- GetValueNormalization 會傳回值的字串形式。 (如果值已經是字串,這個形式將會根據大小寫、輔色等進行正規化。
- GetInputTerms 會傳回輸入句子哪些部分產生屬性名稱、作業和值的相關信息。
- 複製 會返回條件樹狀結構的深層複本。
IRichChunk
每個 IRichChunk 物件都會識別令牌範圍和字串。 IRichChunk 是一個工具介面,用於表示由起始位置和長度所識別的區間資訊(通常是標記的區間)。 這裡資訊包括字串和/或 VARIANT。
IConditionGenerator
應用程式提供的 IConditionGenerator 介面,用於處理命名實體類型的辨識和生成條件樹。 條件產生器會經由 IQueryParser:SetMultiOption提供給 IQueryParser。 IQueryParser 使用目前載入架構的 ISchemaProvider 呼叫 IConditionGenerator::Initialize。 這樣做允許 IConditionGenerator 取得所需的任何架構資訊。 剖析輸入字串時,IQueryParser 呼叫每個 IConditionGenerator的IConditionGenerator::RecognizeNamedEntities 方法,以便報告已辨識的具名實體在輸入字串中的出現情況。 IQueryParser 可以利用目前的語言環境,而且應該使用輸入的標記化處理,因為它需要報告任何具名實體的令牌範圍。
當 IQueryParser 即將產生一個葉節點,且值的語意類型符合 IConditionGenerator的具名實體類型時,IQueryParser 會呼叫 IConditionGenerator::GenerateforLeaf,以取得要生成之節點的資訊。 如果 IConditionGenerator 傳回S_OK,它應該傳回條件樹狀結構(這不一定是分葉節點),並通知 IQueryParser 是否要隱藏通常會產生的替代字符串解譯作為預防措施。
ITokenCollection
ITokenCollection::NumberOfTokens 方法會傳回令牌數目。ITokenCollection::GetToken 傳回第 i個令牌的相關資訊。 開頭和長度是輸入字串中的字元位置。 當有文字覆蓋輸入字串的字元時,回傳的文字才會是非空。 例如,當破折號位於應該被解釋為否定的上下文中時,可以使用NOT來覆寫輸入字串中的破折號。
INamedEntityCollector
IConditionGenerator 會針對所辨識的每個具名實體呼叫 INamedEntityCollector::Add。 範圍是標記範圍。 beginSpan 一定要是這樣嗎? 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 的專屬關聯性。不過,A 與 R 之間的關聯性必須與 B 的目的地類型相同,而且唯一存在的原因就是儲存 B 特有的元數據。這種B的關係據說不是真實的。
- IRelationship::Medadata 會傳回 IMetaData 介面的列舉,每個實體的元數據組各一個。
- IRelationship::DefaultPhrase 會傳回用於重述中此關聯性的預設詞組。 每個關聯性都有一個預設詞組,用以標示,以便生成條件樹的 AQS 或 NQS 重述。
IMetaData
元數據是與實體、關聯性或整個架構相關聯的索引鍵/值組。 因為索引鍵不一定是唯一的,因此元數據集合可以視為多重映射。 會呼叫 IMetaData::GetData 來擷取元數據組的索引鍵和值。
查詢情境
下列案例說明在常見的查詢案例中使用 Windows 搜尋服務中的結構化查詢 API,例如建立條件樹狀目錄和查詢索引。
條件擷取和查詢剖析
建立查詢時,其範圍是藉由告訴系統要搜尋的位置來定義。 這會限制搜尋結果。 定義範圍之後,會套用篩選,並傳回篩選集。 搜尋結果受限於使用分葉節點建置條件樹狀結構,類似於圖表。 然後會擷取這些條件。 條件樹狀結構是分葉條件的布爾值組合(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);
};
如果有一個以上的篩選條件,則會使用 AND 和其他布爾運算符來達成單一樹狀結構。 AND-trees 和 OR-trees 代表其子樹的結合和分離。 NOT 樹狀結構代表其單一子樹的否定。 AQS 提供文字方法來使用布爾運算符達成邏輯表達式,而且通常更簡單。
在下一個範例中,我們會將條件樹狀結構 (ICondition) 轉換成視覺形式。 查詢剖析器會使用 IQueryParser 介面,將 ICondition 轉換成 RTF 格式的查詢字串。 IQueryParser::RestateToString 方法會傳回查詢文字,而 IQueryParser::P arse 方法會產生 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 介面來開發元件或協助程式類別來查詢索引。 這個界面被實作為一個助手類別,輔助 ISearchCatalogManager (以及 ISearchCatalogManager2),並且通過呼叫 ISearchCatalogManager::GetQueryHelper來取得。 如需概念資訊,請參閱使用 ISearchQueryHelper 查詢索引 。
ISearchQueryHelper 允許您:
- 取得連線到 Windows Search 資料庫的 OLE DB 連接字串。
- 將 AQS 使用者查詢轉換為 Windows 搜尋 SQL。
- 指定可在 SQL 中表示但不能以 AQS 表示的查詢限制。
Windows 7 和更新版本支援索引優先順序和數據列集事件。 使用 IRowsetPrioritization 有一個優先順序堆疊,可讓用戶端要求特定查詢中使用的範圍高於一般優先順序。 IRowsetEvents 會提供數據列集中專案的變更通知,包括新增專案、刪除專案,以及修改項目數據。 使用數據列集事件通知可確保現有查詢的結果盡可能最新。 如需概念資訊,請參閱在 Windows 7 中索引優先順序和數據列集事件。
相關主題
-
在 Windows 搜尋服務 中進行編製索引、查詢和通知
-
索引 中包含的內容