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 Search SQL 構文の使用方法の詳細については、「Windows Search SQL 構文を使用したインデックスのクエリ」および「Windows Search 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 プログラミングの概要」を参照してください。 .NET Framework Data Provider for OLE DB の詳細については、System.Data.OleDb 名前空間に関するドキュメントを参照してください。

ADO と ADO.NET の使用

Microsoft ActiveX Data Objects (ADO) と ADO.NET を使用すると、プロバイダーを介してデータベース サーバー内のデータにアクセスして操作するためのクライアント アプリケーションを記述できます。 Windows 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 デスクトップ検索 (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 の使用を簡略化できます。 このインターフェイスは、次の場合に役立ちます。

  • Windows Search データベースに接続するための OLE DB 接続文字列を取得します。
  • ユーザー クエリを 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 デスクトップ検索 (WDS) 2x 互換性: Windows XP および Windows Server 2003 以降を実行しているコンピューターでは、 ISearchDesktop は非推奨です。 代わりに、開発者は ISearchQueryHelper を使用して接続文字列を取得し、ユーザーのクエリを SQL に解析してから、OLE DB を使用してクエリを実行する必要があります。

search-ms プロトコルの使用

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

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

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

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

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

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

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