使用 SQL 和 AQS 方法查询索引

有多种方法可以使用 Windows Search 来查询索引。 本主题概述了基于高级查询语法 (AQS) 与结构化查询语言 (SQL) 的方法。

本主题的组织方式如下:

基于 SQL 的查询

SQL 是用于定义查询的文本语言。 SQL 在很多不同的数据库技术中十分常见。 Windows 搜索会使用 SQL、实现它的子集,并通过向该语言添加元素来进行扩展。 Windows 搜索使用的 Windows 搜索 SQL 会扩展标准 SQL-92 和 SQL-99 数据库查询语法的其中一部分,从而增强其针对基于文本的搜索的有用性。 Windows 搜索 SQL 的所有功能均与 Windows XP 和 Windows Server 2003 及更高版本上的 Windows 搜索相兼容。

有关使用 Windows 搜索 SQL 语法的详细信息,请参阅使用 Windows 搜索 SQL 语法查询索引Windows 搜索 SQL 语法概述

用于查询索引的以下方法均基于 SQL。

使用 OLE DB

对象链接和嵌入数据库 (OLE DB) 是一个组件对象模型 (COM) API,它可用于统一地访问不同类型的数据存储,其中包括非关系数据库(如电子表格)。 OLE DB 通过一组抽象(其中包括 Shell 数据源、会话、命令和行集)将数据存储与访问数据存储的应用程序区分开来。 OLE DB 提供程序是用于实现 OLE DB 接口的软件组件,它可向来自特定数据存储的应用程序提供数据。

你可使用 C# 中的 OleDbConnection 和 OleDbSession 对象,以及使用 C++ 中内置于活动模板库 (ATL) 的 OLE DB 支持(通过 atlclidb.h)以编程方式访问 Windows 搜索 OLE DB 提供程序。 必须设置的唯一属性为提供程序字符串。

你可使用以下字符串:

provider=Search.CollatorDSO;EXTENDED PROPERTIES="Application=Windows"

或者,也可通过调用 ISearchQueryHelper::get_ConnectionString 来获取连接字符串。 有关示例,请参阅使用 ISearchQueryHelper

注意

Windows 搜索 OLE DB 提供程序为只读状态,且支持 SELECT 和 GROUP ON 语句。 它不支持 INSERT 和 DELETE 语句。

#include <atldbcli.h>
CDataSource cDataSource;
hr = cDataSource.OpenFromInitializationString(L"provider=Search.CollatorDSO.1;EXTENDED PROPERTIES=\"Application=Windows\"");

if (SUCCEEDED(hr))
{
    CSession cSession;
    hr = cSession.Open(cDataSource);

    if (SUCCEEDED(hr))
    {
        CCommand<CDynamicAccessor, CRowset> cCommand;
        hr = cCommand.Open(cSession, pszSQL);

        if (SUCCEEDED(hr))
        {
            for (hr = cCommand.MoveFirst(); S_OK == hr; hr = cCommand.MoveNext())
            {
                for (DBORDINAL i = 1; i <= cCommand.GetColumnCount(); i++)
                {
                    PCWSTR pszName = cCommand.GetColumnName(i);
                    // do something with the column here
                }
            }
            cCommand.Close();
        }
    }
}

有关 OLE DB 的详细信息,请参阅 OLE DB 编程概述。 有关适用于 OLE DB 的 .NET Framework 数据提供程序的信息,请参阅 System.Data.OleDb 命名空间文档。

使用 ADO 和 ADO.NET

Microsoft ActiveX 数据对象 (ADO) 和 ADO.NET 允许编写客户端应用程序,以便通过提供程序来访问和操作数据库服务器中的数据。 Windows 搜索是一种只读技术:你可使用桌面搜索来检索数据,但无法使用 Windows 搜索来更改数据。 但是,你可将搜索结果传递给能更改数据的技术。

以下代码示例演示了如何建立与数据源的连接,使用 Windows 搜索 SQL SELECT 语句来创建和打开 RecordSet,以及从索引获取五个最大文件的 URL。

注意

有关如何获取连接字符串的信息,请参阅使用 ISearchQueryHelper 查询索引ISearchQueryHelper::get_Connection 字符串

ADO 和 VBScript

'To run this snippet, save it to a file and run it using cscript.exe from a command line.
'Running the .vbs file with Windows Script Host may cause dialog boxes to open for each item returned from the index.

On Error Resume Next

Set objConnection = CreateObject("ADODB.Connection")
Set objRecordSet = CreateObject("ADODB.Recordset")

objConnection.Open "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"

objRecordSet.Open "SELECT Top 5 System.ItemPathDisplay FROM SYSTEMINDEX WHERE scope='file:' ORDER BY System.Size DESC", objConnection

objRecordSet.MoveFirst
Do Until objRecordset.EOF
    Wscript.Echo objRecordset.Fields.Item("System.ItemPathDisplay")
    objRecordset.MoveNext
Loop

ADO 和 C++

#import "msado15.dll" rename_namespace("ADO") rename("EOF", "EndOfFile") implementation_only

ADO::_ConnectionPtr connection = NULL;
HRESULT hr = connection.CreateInstance(__uuidof(ADO::Connection));
if (SUCCEEDED(hr))
{
    ADO::_RecordsetPtr recordset = NULL;
    hr = recordset.CreateInstance(__uuidof(ADO::Recordset));
    if (SUCCEEDED(hr))
    {
        connection->CursorLocation = ADO::adUseClient;
        hr = connection->Open(L"Provider=Search.CollatorDSO;Extended Properties='Application=Windows';",
            L"", L"", ADO::adConnectUnspecified);
        if (SUCCEEDED(hr))
        {
            hr = recordset->Open("SELECT Top 5 System.ItemPathDisplay FROM SYSTEMINDEX WHERE scope='file:' ORDER BY System.Size DESC",
            connection.GetInterfacePtr(), ADO::adOpenForwardOnly, ADO::adLockReadOnly, ADO::adCmdText);
            if (SUCCEEDED(hr))
            {
                while (!recordset->EndOfFile)
                {
                    _variant_t var;
                    var = recordset->Fields->GetItem(L"System.ItemPathDisplay")->GetValue();
                    std::cout << static_cast<char *>(_bstr_t(var.bstrVal)) << std::endl;
                    recordset->MoveNext();
                };
                recordset->Close();
            }
            connection->Close();
        }
    }
}

ADO 和 VisualBasic

首次添加对项目中 ADODB 的引用

Dim con As ADODB.Connection
Dim rst As ADODB.Recordset

con = New ADODB.Connection
rst = New ADODB.Recordset

Dim sConString As String
Dim sSQLString As String

sConString = "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
con.Open(sConString)

sSQLString = "SELECT Top 5 System.ItemPathDisplay FROM SYSTEMINDEX
                WHERE scope='file:'
                ORDER BY System.Size DESC"

rst = con.Execute(sSQLString)

Do Until (rst.EOF)
    Print(1, rst("System.ItemPathDisplay").Value)
    rst.MoveNext
Loop

rst.Close
rst = Nothing

con.Close
con = Nothing

ADO.NET 和 C#

string query = @"SELECT Top 5 System.ItemPathDisplay FROM SYSTEMINDEX
                WHERE scope='file:'
                ORDER BY System.Size DESC";

using (OleDbConnection objConnection =
    new OleDbConnection
    ("Provider=Search.CollatorDSO.1;Extended?Properties='Application=Windows';"))
{
    objConnection.Open();
    OleDbCommand cmd = new OleDbCommand(query, objConnection);
    using (OleDbDataReader rdr = cmd.ExecuteReader())
    {
        for (int i = 0; i < rdr.FieldCount; i++)
        {
            Console.Write(rdr.GetName(i));
            Console.Write('\t');
        }
        while (rdr.Read())
        {
            Console.WriteLine();
            for (int i = 0; i < rdr.FieldCount; i++)
            {
                Console.Write(rdr[i]);
                Console.Write('\t');
            }
        }
        Console.ReadKey();
    }
}

在本地与远程查询中使用 SQL

你可在本地或远程执行查询。 以下示例显示了使用 FROM 子句的本地查询。 本地查询仅会查询本地 SystemIndex 目录。

FROM SystemIndex

以下示例显示了使用 FROM 子句的远程查询。 添加 ComputerName 可将前一示例转换为远程查询。

FROM [<ComputerName>.]SystemIndex

默认情况下,Windows XP 和 Windows Server 2003 均未安装 Windows 搜索。 仅 Windows 搜索 4 (WS4) 提供远程查询支持。 早期版本的 Windows 桌面搜索 (WDS) 不支持远程查询,例如 3.01 及更早版本。 借助 Windows 资源管理器,你可查询远程计算机的本地索引是否存在某些文件系统项目(即,由“fil:”协议处理的项目)。

若要通过远程查询来检索项目,该项目则须满足以下要求:

  • 可通过通用命名约定 (UNC) 路径进行访问。
  • 存在于客户端有权访问的远程计算机上。
  • 已将其安全性设为允许客户端具有读取访问权限。

Windows 资源管理器具有共享项目的功能,其中包括网络和共享中心内的“公共”共享 (\\Machine\Public\...),以及通过共享向导来共享的项目的“用户”共享 (\\Machine\Users\...)。 共享文件夹后,可通过在 FROM 子句中指定远程计算机的计算机名称并在 SCOPE 子句中指定远程计算机上的 UNC 路径来查询本地索引,如以下示例所示:

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

基于 AQS 的查询

AQS 是 Windows 搜索用于查询索引以及优化和缩小搜索参数范围的默认查询语法。 虽然 AQS 主要面向用户,但开发人员可使用它并以编程方式生成查询。 Windows 7 中已引入规范 AQS,且必须在 Windows 7 及更高版本中使用并以编程方式来生成 AQS 查询。 有关 AQS 的详细信息,请参阅以编程方式使用高级查询语法

用于查询索引的以下方法均基于 AQS。

使用 ISearchQueryHelper

你可使用 ISearchQueryHelper 接口来开发组件或帮助程序类,从而查询索引。如此一来,你便可充分利用系统的某些功能并简化 Windows 搜索的使用。 此接口可帮助你:

  • 获取 OLE DB 连接字符串以连接到 Windows 搜索数据库。
  • 将用户查询从 AQS 转换为 Windows 搜索 SQL。

此接口会作为 ISearchCatalogManager 的帮助程序类来实现,且可通过调用 ISearchCatalogManager::GetQueryHelper 来获取,如以下 C++ 示例所示。

HRESULT GetQueryHelper(ISearchQueryHelper **ppQueryHelper)
{
    *ppQueryHelper = NULL;

    // Create an instance of the search manager

    ISearchManager *pSearchManager;
    HRESULT hr = CoCreateInstance(__uuidof(CSearchManager), NULL, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&pSearchManager));
    if (SUCCEEDED(hr))
    {
        // Get the catalog manager from the search manager
        ISearchCatalogManager *pSearchCatalogManager;
        hr = pSearchManager->GetCatalog(L"SystemIndex", &pSearchCatalogManager);
        if (SUCCEEDED(hr))
        {
            // Get the query helper from the catalog manager
            hr = pSearchCatalogManager->GetQueryHelper(ppQueryHelper);
            pSearchCatalogManager->Release();
        }
        pSearchManager->Release();
    }

    return hr;
}

若要实现 ISearchQueryHelper 接口,请参阅使用 ISearchQueryHelper 接口ISearchQueryHelper 参考主题。

注意

旧版 Microsoft Windows 桌面搜索 (WDS) 2x 兼容性:在运行 Windows XP 和 Windows Server 2003 及更高版本的计算机上, ISearchDesktop 已被弃用。 相反,开发人员应使用 ISearchQueryHelper 来获取连接字符串、将用户的查询分析为 SQL,然后通过 OLE DB 进行查询。

使用 search-ms 协议

search-ms 应用程序协议是启动应用程序(如 Windows 资源管理器)以查询 Windows 搜索索引的约定。 它允许使用参数值参数(包括属性参数、先前保存的搜索、高级查询语法 (AQS)、自然查询语法 (NQS) 和语言代码标识符 (LCID))为索引器和查询自身生成查询。

有关 search-ms 协议语法的详细信息,请参阅使用 search-ms 协议查询索引

以编程方式查询索引

使用 ISearchQueryHelper 查询索引

使用 search-ms 协议查询索引

使用 Windows 搜索 SQL 语法查询索引

以编程方式使用高级查询语法