SQLと AQS のアプローチを使用してインデックスを照会する

Windows Search を使用してインデックスのクエリを実行するには、いくつかの方法があります。 このトピックでは、高度なクエリ構文 (AQS) と構造化照会言語 (SQL) ベースのアプローチについて説明します。

このトピックは次のように整理されています。

SQL ベースのクエリ

SQLは、クエリを定義するテキスト言語です。 SQLは、さまざまなデータベース テクノロジで一般的です。 Windows Search では、SQLを使用し、そのサブセットを実装し、言語に要素を追加して拡張します。 Windows Search で使用される Windows Search SQLは、標準の SQL-92 および SQL-99 データベース クエリ構文の一部を拡張して、テキストベースの検索での有用性を高めます。 Windows Search SQLのすべての機能は、Windows XP および Windows Server 2003 以降の Windows Search と互換性があります。

Windows検索SQL構文の使用方法の詳細については、「Windows検索SQL構文を使用したインデックスの照会」および「Windows検索SQL構文の概要」を参照してください。

インデックスのクエリを実行するための次の方法は、SQLベースです。

OLE DB の使用

オブジェクト リンクおよび埋め込みデータベース (OLE DB) は、スプレッドシートなどの非リレーショナル データベースを含め、さまざまな種類のデータ ストアに一様にアクセスできるコンポーネント オブジェクト モデル (COM) API です。 OLE DB は、シェル データ ソース、セッション、コマンド、および行セットを含む一連の抽象化を使用して、データ ストアをアプリケーションから分離します。 OLE DB プロバイダーは、OLE DB インターフェイスを実装して、特定のデータ ストアからアプリケーションにデータを提供するソフトウェア コンポーネントです。

Windows Search OLE DB プロバイダーにプログラムでアクセスするには、C# で OleDbConnection オブジェクトと OleDbSession オブジェクトを使用し、C++ の Active Template Library (ATL) に組み込まれている OLE DB サポートを使用します (atlclidb.h 経由)。 設定する必要がある唯一のプロパティは、プロバイダー文字列です。

次の文字列を使用できます。

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

または、 ISearchQueryHelper::get_ConnectionString を呼び出して接続文字列を取得することもできます。 例については、 ISearchQueryHelper の使用を参照してください。

Note

Windows Search 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 Data Providerについては、System.Data.OleDb 名前空間のドキュメントを参照してください。

ADO と ADO.NET の使用

Microsoft ActiveX データ オブジェクト (ADO) と ADO.NET を使用すると、プロバイダーを介してデータベース サーバー内のデータにアクセスして操作するクライアント アプリケーションを作成できます。 Windows検索は読み取り専用テクノロジです。Desktop Search を使用してデータを取得できますが、Windows Search を使用してデータを変更することはできません。 ただし、データを変更できるテクノロジに検索結果を渡すことができます。

次のコード例では、データ ソースへの接続を開き、Windows Search SQL SELECT ステートメントを使用して RecordSet を作成して開き、インデックスから 5 つの最大ファイルの URL を取得する方法を示します。

Note

接続文字列を取得する方法については、「 ISearchQueryHelper を使用したインデックスのクエリ」および 「ISearchQueryHelper::get_Connection String」を参照してください。

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 Search がインストールされていません。 リモート クエリのサポートを提供するのは、Windows Search 4 (WS4) のみです。 以前のバージョンの Windows Desktop Search (WDS) (3.01 以前など) では、リモート クエリはサポートされていません。 Windows エクスプローラーを使用すると、リモート コンピューターのローカル インデックスに対してファイル システム項目 ("file:" プロトコルによって処理される項目) を照会できます。

リモート クエリで項目を取得するには、項目が次の要件を満たしている必要があります。

  • 汎用名前付け規則 (UNC) パスを使用してアクセスできます。
  • クライアントがアクセスできるリモート コンピューター上に存在します。
  • クライアントが読み取りアクセスを許可するようにセキュリティを設定します。

Windows エクスプローラーには、ネットワークと共有センターの "パブリック" 共有 (\\Machine\Public\...)、共有ウィザードで共有されるアイテムの "ユーザー" 共有 (\\Machine\Users\...) など、アイテムを共有するための機能があります。 フォルダーを共有した後は、次の例に示すように、FROM 句でリモート コンピューターのコンピューター名と SCOPE 句でリモート コンピューターの UNC パスを指定することで、ローカル インデックスのクエリを実行できます。

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

AQS ベースのクエリ

AQS は、インデックスのクエリを実行したり、検索パラメーターを絞り込んだり絞り込んだりするために、Windows Search で使用される既定のクエリ構文です。 AQS は主にユーザー向けですが、開発者はプログラムでクエリを作成するために使用できます。 Windows 7 個の正規 AQS が導入されました。プログラムで AQS クエリを生成するには、Windows 7 以降で使用する必要があります。 AQS の詳細については、「 プログラムによる高度なクエリ構文の使用」を参照してください。

インデックスのクエリを実行するための次の方法は、AQS ベースです。

ISearchQueryHelper の使用

ISearchQueryHelper インターフェイスを使用してインデックスのクエリを実行するコンポーネントまたはヘルパー クラスを開発できます。これにより、システムの一部の機能を利用し、Windows Search の使用を簡略化できます。 このインターフェイスは、次の場合に役立ちます。

  • OLE DB 接続文字列を取得して、Windows Search データベースに接続します。
  • ユーザー クエリを AQS から Windows Search SQLに変換します。

このインターフェイスは ISearchCatalogManager のヘルパー クラスとして実装され、次の C++ の例に示すように ISearchCatalogManager::GetQueryHelper を呼び出すことによって取得されます。

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 リファレンス トピックの使用を参照してください。

Note

従来の Microsoft Windows Desktop Search (WDS) 2x 互換性: XP および Windows Server 2003 以降Windows実行しているコンピューターでは、ISearchDesktop は非推奨とされます。 代わりに、開発者は ISearchQueryHelper を使用して接続文字列を取得し、ユーザーのクエリを解析してSQLし、OLE DB を使用してクエリを実行する必要があります。

search-ms プロトコルの使用

search-msアプリケーション プロトコルは、Windows Explorer などのアプリケーションを起動して、Windows Search インデックスに対してクエリを実行するための規則です。 これにより、プロパティ引数、以前に保存した検索、高度なクエリ構文 (AQS)、自然クエリ構文 (NQS)、およびインデクサーとクエリ自体の両方の言語コード識別子 (LCID) を含むパラメーター値引数を使用してクエリを構築できます。

search-ms プロトコル構文の詳細については、 search-ms プロトコルを使用したインデックスの照会を参照してください。

プログラムによるインデックスのクエリ

ISearchQueryHelper を使用したインデックスのクエリ

search-ms プロトコルを使用したインデックスのクエリ

Windows検索SQL構文を使用したインデックスのクエリ

プログラムによる高度なクエリ構文の使用