Exchange で EWS を使用して AQS 検索を実行する

EWS マネージ API または EWS アプリケーションで、クエリ文字列および AQS を使用して検索する方法を確認します。

クエリ文字列は、検索条件を表現する検索フィルターに代わる方法を提供します。 クエリ文字列を使用する最大の利点は、検索するプロパティを 1 つも指定する必要がないということです。 値を指定するだけで、アイテム上の一般的に使用されるすべてのフィールドに検索が適用されます。 単純な値の代わりに高度な検索テクニック (AQS) を使用して検索を絞り込むこともできます。 ただし、クエリ文字列には、ツールボックスに追加する前に注意すべき次の制限があります。

  • 特定のプロパティを検索する機能に制限がある。 クエリ文字列で単純な値を検索すると、検索はすべてのインデックス付きプロパティに対して実行されます。 特定のプロパティに検索を絞り込むことはできますが、AQS 文字列で使用できるプロパティは限定されます。 検索するプロパティが AQS で使用可能なプロパティのいずれでもない場合は、検索フィルターを使用することを検討してください。

  • カスタム プロパティは検索されない。 クエリ文字列の検索はインデックスに対して実行されますが、カスタム プロパティはそのインデックスに含まれません。 カスタム プロパティを検索する必要がある場合は、代わりに検索フィルターを使用してください。

  • 文字列検索の制御が限定されている。 クエリ文字列の検索は常に、大文字と小文字の違いを無視し、部分文字列の検索になります。 大文字と小文字を区別する場合、プレフィックスの検索、完全一致の検索を実行する場合は、検索フィルターを使用してください。

  • フォルダーまたは検索フォルダーでは使用できない。 フォルダーを検索するための EWS 操作では、クエリ文字列の使用がサポートされていません。 さらに、検索フォルダーは、クエリ文字列をサポートしません。 どちらの場合も、検索フィルターが唯一のオプションになります。

クエリ文字列の作成

EWS マネージ API および EWS のクエリ文字列は、AQS 構文の一部であると解釈されます。 AQS 文字列は、値またはキーワード/値のペアのいずれかで構成され、コロン (:) で区切られます。

keyword:value

キーワードを使用せずに値を指定した場合、すべてのインデックス付きプロパティでその値が検索されます。 キーワードが値とペアになっている場合、キーワードは対応する値を検索するプロパティを指定します。

表 1. サポートされている AQS キーワード

キーワード 値の型
subject
文字列
subject:project
body
文字列
body:sales figures
attachment
文字列
attachment:report
to
文字列
to:"Sadie Daniels"
from
文字列
from:hope
cc
文字列
cc:"Ronnie Sturgis"
bcc
文字列
bcc:mack
participants
文字列
participants:sadie
category
文字列
category:project
importance
文字列
importance:high
kind
アイテムの種類
kind:meetings
sent
日付
sent:12/10/2013
received
日付
received:yesterday
hasattachment
ブール型
Has attachment:true
isflagged
ブール型
isflagged:true
isread
ブール型
isread:false
size
数値
size:>5000

別の値の型がどのように動作するかを見てみましょう。

文字列値型の使用

文字列値型は既定で、大文字と小文字を区別しないプレフィックス部分文字列として検索されます。 つまり、subject:project を検索すると、次の項目のいずれかと一致します。

  • Project meeting notes

  • Do you have the project plans?

  • December sales projections

文字列を引用符で囲むことによってプレフィックスと一致させるのではなく、完全に一致する単語を要求するように検索を変更できます。 subject:"project" を検索すると、候補一覧から「December sales projections」値が削除されます。 この場合でも、値は大文字と小文字が区別されないことに注意してください。

クエリ文字列に複数の単語を使用する場合、両方の単語が検索対象フィールドにあるものが一致します。 たとえば、subject:project plan を検索すると、次の項目のいずれかと一致します。

  • Project plan

  • Do you have the project plans?

  • Please send me the plan for our project

  • Planning project milestones

複数の単語を引用符で囲むと、それらは 1 つの句として扱われます。 subject:"project plan" を検索すると、先ほどのリストの「Project plan」という件名だけが一致します。

アイテムの種類の値の型の使用

kind キーワードで次のアイテムの種類の値を使用して、検索結果をメールや会議出席依頼などの特定の種類のアイテムのみに制限することができます。

  • 連絡先
  • docs
  • email
  • faxes
  • im (インスタント メッセージに相当)
  • journals
  • meetings (予定や会議出席依頼に相当)
  • notes
  • posts
  • rssfeeds
  • tasks
  • voicemail

日付値型の使用

日付値型はいくつかの異なる方法で検索できます。 最も単純なのは特定の日付を検索することです。 received:12/11/2013 で検索すると、2013 年 12 月 11 日に受信したすべてのアイテムが返されます。 ただし、指定の仕方を簡単な形式にすることもできます。 received:12/11 で検索すると、現在の年の 12 月 11 日に受信したすべてのアイテムが返されます。

別のオプションとして、月の名前を使用することができます。 received:December 11, 2013 または December 11 で検索すると、received:12/11/2013 および received:12/11 と同じ結果を取得できます。 received:December で検索し、現在の年の 12 月に受信したすべてのアイテムを取得することもできます。

週の曜日の名前を使用することもできます。 received:Tuesday で検索すると、現在の週の火曜日に受信したすべてのアイテムが返されます。

日付値型は、現在の時刻を基準にした検索のキーワードのセットもサポートします。 サポートされているキーワードは次のとおりです。

  • 今日
  • tomorrow
  • yesterday
  • this week
  • last week
  • next month
  • past month
  • coming year

日付値型は、greater than または less than のような関係演算子で比較したり、範囲演算子 .. を使用して範囲として指定したりすることもできます。たとえば、received:>11/30/2013, sent:>=yesterday、received:12/1/2013..today はすべて、有効なクエリ文字列です。

ブール値型の使用

ブール値型は "true" または "false" にできます。 値は大文字と小文字を区別しないので、isread:false と isread:FALSE で生成される結果は同じです。

数値型の使用

数値型は、完全一致として検索できますが、greater than または less than のような関係演算子を使用して検索することもできます。 たとえば、size:10000 では、正確に 10000 バイトのサイズを持つアイテムのみが返されますが、size:>=10000 では 10000 バイト以上のサイズを持つアイテムが返されます。 範囲演算子 (..) を使用して範囲を指定することもできます。 たとえば、size:7000..8000 ではサイズが 7000 と 8000 の間のアイテムが返されます。

論理演算子の使用

クエリ文字列は、次の論理演算子をサポートします。

表 2. サポートされる論理演算子

演算子
AND
project AND from:"Sadie Daniels"
subject:(project AND plan)
OR
subject:meeting OR from:"Hope Gross"
from:("Sadie Daniels" OR "Hope Gross")
NOT
NOT from:"Ronnie Sturgis"
received:NOT today

これらの演算子を使用して、複数の条件を結合したり、1 つのキーワード/値のペア内で複数の値を結合したりできることに注意してください。 ただし、1 つのキーワード/値ペアで複数の値を結合する場合は、かっこを使用して複数の値を囲む必要があります。 その理由を理解するために、from:"Sadie Daniels" OR "Hope Gross" で検索してみてください。 この検索は、実際には次の条件として解釈されます。

  • アイテムが Sadie Daniels からのもの、または

  • アイテムのインデックス付きプロパティのいずれかに「Hope Gross」という語句がある。

対照的に、from:("Sadie Daniels" OR "Hope Gross") は次のように解釈されます。

  • アイテムが Sadie Daniels からのもの、または

  • アイテムが Hope Gross からのもの

複数の条件が指定されているものの論理演算子は含まれていない場合の既定の演算子は AND です。 たとえば、has attachment:true subject:project は has:attachment:true AND subject:project と同じです。

例: クエリ文字列と EWS マネージ API を使用してアイテムを検索する

この例では、SearchWithQueryString というメソッドが定義されています。 パラメーターとして、ExchangeService オブジェクト、WellKnownFolderName オブジェクト、クエリ文字列を表す string オブジェクトを取ります。 この例では、ExchangeService オブジェクトは Credentials プロパティと Url プロパティの有効な値で初期化されているものとします。

using Microsoft.Exchange.WebServices.Data;
static void SearchWithQueryString(ExchangeService service, WellKnownFolderName folder, string queryString)
{
    // Limit the result set to 10 items.
    ItemView view = new ItemView(10);
    view.PropertySet = new PropertySet(ItemSchema.Subject,
                                       ItemSchema.DateTimeReceived,
                                       ItemSchema.Size,
                                       ItemSchema.Importance,
                                       EmailMessageSchema.IsRead);
    // Item searches do not support Deep traversal.
    view.Traversal = ItemTraversal.Shallow;
    // Sorting
    view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
    try
    {
        // Execute the search based on the query string.
        // Example: "subject:project plan"
        FindItemsResults<Item> results = service.FindItems(folder, queryString, view);
        foreach (Item item in results.Items)
        {
            Console.WriteLine("Subject: {0}", item.Subject);
            Console.WriteLine("Received: {0}", item.DateTimeReceived.ToString());
            Console.WriteLine("Size: {0}", item.Size.ToString());
            Console.WriteLine("Importance: {0}", item.Importance.ToString());
            if (item is EmailMessage)
            {
                EmailMessage message = item as EmailMessage;
                Console.WriteLine("Read: {0}", message.IsRead.ToString());
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception while enumerating results: {0}", ex.Message);
    }
}

このメソッドを使用して、この例のように、件名に「project plan」という語句が含まれるすべてのアイテムを検索することができます。

string queryString = "subject:\"project plan\"";
SearchWithQueryString(service, WellKnownFolderName.Inbox, queryString);

例:クエリ文字列と EWS を使用してアイテムを検索する

この例では、SOAP FindItem 要求で、件名に「project plan」という語句が含まれる受信トレイ内のすべてのアイテムを検索します。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" 
    xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types" 
    xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2013" />
  </soap:Header>
  <soap:Body>
    <m:FindItem Traversal="Shallow">
      <m:ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:FieldURI FieldURI="item:Subject" />
          <t:FieldURI FieldURI="item:DateTimeReceived" />
          <t:FieldURI FieldURI="item:Size" />
          <t:FieldURI FieldURI="item:Importance" />
          <t:FieldURI FieldURI="message:IsRead" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:IndexedPageItemView MaxEntriesReturned="10" Offset="0" BasePoint="Beginning" />
      <m:SortOrder>
        <t:FieldOrder Order="Descending">
          <t:FieldURI FieldURI="item:DateTimeReceived" />
        </t:FieldOrder>
      </m:SortOrder>
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="inbox" />
      </m:ParentFolderIds>
      <m:QueryString>subject:"project plan"</m:QueryString>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

次の例は、検索結果を含むサーバーからの応答を示しています。

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15" MinorVersion="0" MajorBuildNumber="712" MinorBuildNumber="22" Version="V2_3" 
        xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types" 
        xmlns="https://schemas.microsoft.com/exchange/services/2006/types" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <m:FindItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:FindItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:RootFolder IndexedPagingOffset="1" TotalItemsInView="1" IncludesLastItemInRange="true">
            <t:Items>
              <t:Message>
                <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                <t:Subject>project plan</t:Subject>
                <t:DateTimeReceived>2013-12-11T15:42:02Z</t:DateTimeReceived>
                <t:Size>7406</t:Size>
                <t:Importance>Normal</t:Importance>
                <t:IsRead>false</t:IsRead>
              </t:Message>
            </t:Items>
          </m:RootFolder>
        </m:FindItemResponseMessage>
      </m:ResponseMessages>
    </m:FindItemResponse>
  </s:Body>
</s:Envelope>

関連項目