Exchange で EWS とともに検索フィルターを使用する

EWS マネージ API または Exchange の EWS によって検索ファイルを使用する方法を確認します。

検索フィルターは、EWS Managed API または EWS アプリケーションで検索条件を記述するための主要なツールです。クエリ文字列ではなく、検索フィルターを使用して以下を実行することをお勧めします。

  • 特定のプロパティまたはプロパティのセットを検索します。
  • 複数の検索条件を使用して検索します。

検索フィルターは、次のいずれかを実行する場合、唯一のオプションです。

  • カスタム プロパティを検索します。
  • 大文字小文字を区別して文字列の検索を実行します。
  • プレフィックスまたは完全に一致する文字列の検索を実行します。
  • ビットマスクの検索を実行します。
  • 値に関係なく特定のプロパティ セットを持つアイテムを検索します。
  • フォルダーを検索します。
  • 検索フォルダーを作成します。

必要な検索フィルターの種類を決定します。

検索フィルターを作成する前に、まず必要なフィルターの種類を決定します。 フィルターの種類は、EWS マネージ API では SearchFilter クラスの子クラスとして、EWS では Restriction 要素の子要素として実装されます。

表 1. 検索フィルターの種類

フィルターの種類 EWS マネージ API のクラス EWS の要素 説明
包含フィルター
ContainsSubstring
Contains
文字列比較に使用するのに最適なフィルターの種類です。大文字小文字の区別、空白を無視するかどうかを制御でき、包含モードを設定できます。
ビットマスク フィルター
ExcludesBitmask
Excludes
整数のプロパティをビットマスクとして検索し、指定されたビットマスクに対応するビットが設定されていない結果のみを返すことができます。
存在フィルター
Exists
Exists
値に関係なく指定したプロパティを持つすべてのアイテムを返します。
等値フィルター
IsEqualTo
IsNotEqualTo
IsEqualTo
IsNotEqualTo
指定された定数値または別のプロパティの値のいずれかを持つ、指定されたプロパティの値を比較し、IsEqualTo フィルターの場合は同じ値を持つすべてのアイテムを返し、IsNotEqualTo フィルターの場合は非等値を返します。
関係テスト フィルター
IsGreaterThan
IsGreaterThanOrEqualTo
IsLessThan
IsLessThanOrEqualTo
IsGreaterThan
IsGreaterThanOrEqualTo
IsLessThan
IsLessThanOrEqualTo
指定された定数値または別のプロパティのいずれかに該当する関係において、指定したプロパティの値を持つすべてのアイテムを返します。 たとえば、IsGreaterThan フィルターは指定されたプロパティの指定された値よりも大きい値を持つすべてのアイテムを返します。
否定フィルター
Not
Not
他のフィルターの結果を否定します。
複合フィルター
SearchFilterCollection
And
Or
複数のフィルターを組み合わせて複雑な検索条件を指定できます。

包含フィルター

包含フィルターは、文字列のプロパティを検索するための最適な選択肢です。包含フィルターを使用すると、包含モードと比較モードを設定することによって、大文字小文字の区別や空白の処理方法など、文字列の一致のさまざまな面を制御することができます。

EWS マネージ API での包含フィルター

EWS マネージ API を使用している場合、ContainsSubstring クラスの ContainmentMode プロパティを使用して包含モードを設定し、ContainsSubstring クラスの ComparisonMode プロパティを使用して比較モードを設定します。 次の例では、"meeting notes" (会議メモ) という部分文字列を、アイテムの件名フィールドで検索する検索フィルターを作成する方法を示します。 この例では大文字と小文字は無視されますが、空白は無視されません。

// Find all items with a subject that contain the substring
// "meeting notes", regardless of case.
// Matches include:
//   - meeting notes
//   - Meeting Notes
//   - Here are my meeting notes
SearchFilter.ContainsSubstring subjectFilter = new SearchFilter.ContainsSubstring(ItemSchema.Subject,
    "meeting notes", ContainmentMode.Substring, ComparisonMode.IgnoreCase);

EWS での包含フィルター

EWS では、Contains 要素の ContainmentMode 属性を使用して包含モードを設定し、Contains 要素の ContainmentComparison 属性を使用して比較モードを設定します。 次の例では、"meeting notes" (会議メモ) という部分文字列を、アイテムの件名フィールドで検索するための検索フィルターを作成する方法を示します。 この例では大文字と小文字は無視されますが、空白は無視されません。

<t:Contains ContainmentMode="Substring" ContainmentComparison="IgnoreCase">
  <t:FieldURI FieldURI="item:Subject" />
  <t:Constant Value="meeting notes" />
</t:Contains>

ビットマスク フィルター

ビットマスク フィルターを使用すると、整数のプロパティをビットマスクとして検索し、指定されたプロパティの値に特定のビットが設定されていない結果を返すことができます。

EWS マネージ API でのビットマスク フィルター

次の例では、EWS マネージ API を使用して、(この記事の「例: 検索フィルターと EWS マネージ API を使用してアイテムを検索する」セクションで定義された) ItemIndex カスタム プロパティの値を持ち、2 番目のビット (バイナリの 10) が設定されていないすべてのアイテムを返す検索フィルターを作成する方法を示します。

// Find all items with a value of the custom property that does not
// have the second bit (0010) set.
// Matches include:
//   - Property not set
//   - 1 (0001)
//   - 4 (0100)
//   - 5 (0101)
//   - 8 (1000)
SearchFilter.ExcludesBitmask bit2NotSetFilter = 
    new SearchFilter.ExcludesBitmask(customPropDefinition, 2);

EWS でのビットマスク フィルター

次の例では、EWS を使用して、(この記事の「例: 検索フィルターと EWS マネージ API を使用してアイテムを検索する」セクションで定義された) ItemIndex カスタム プロパティの値を持ち、2 番目のビット (バイナリの 10) が設定されていないすべてのアイテムを返す検索フィルターを作成する方法を示します。

<t:Excludes>
  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
  <t:Bitmask Value="2" />
</t:Excludes>

存在フィルター

存在フィルターを使用すると、値に関係なく特定のプロパティが設定されているアイテムを検索できます。

EWS マネージ API での存在フィルター

次の例は、ItemIndex カスタム プロパティが設定されているすべてのアイテムを返す検索フィルターを作成する方法を示しています。

// Find all items that have the custom property set.
SearchFilter.Exists customPropSetFilter =
    new SearchFilter.Exists(customPropDefinition);

EWS での存在フィルター

次の例は、ItemIndex カスタム プロパティが設定されているすべてのアイテムを返す検索フィルターを作成する方法を示しています。

<t:Exists>
  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
</t:Exists>

等値フィルター

等値フィルターでは、特定の値に等しいか、特定の値に等しくない、指定されたプロパティの値を持つすべてのアイテムを検索できます。比較する値は、定数値、またはアイテムごとの別のプロパティの値のいずれかにできます。

EWS Managed API での等値フィルター

次の例は、EWS Managed API を使用して、読み取られていないすべてのアイテムを返す検索フィルターを作成する方法を示しています。

// Find all items that are not marked as read.
SearchFilter.IsEqualTo unreadFilter =
    new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);

次の例は、アイテムのサイズに等しくない ItemIndex プロパティの値を持つすべてのアイテムを返す検索フィルターを作成する方法を示しています。

// Find all items that are marked as read.
SearchFilter.IsNotEqualTo indexNotEqualToSizeFilter =
    new SearchFilter.IsNotEqualTo(customPropDefinition, ItemSchema.Size);

EWS での等値フィルター

次の例は、EWS を使用して、読み取られていないすべてのアイテムを返す検索フィルターを作成する方法を示しています。

<t:IsEqualTo>
  <t:FieldURI FieldURI="message:IsRead" />
  <t:FieldURIOrConstant>
    <t:Constant Value="false" />
  </t:FieldURIOrConstant>
</t:IsEqualTo>

次の例は、アイテムのサイズに等しくない ItemIndex プロパティの値を持つすべてのアイテムを返す検索フィルターを作成する方法を示しています。

<t:IsNotEqualTo>
  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
  <t:FieldURIOrConstant>
    <t:FieldURI FieldURI="item:Size" />
  </t:FieldURIOrConstant>
</t:IsNotEqualTo>

関係テスト フィルター

関係テスト フィルターでは、指定された値より大きい (>)、指定された値以上である (>=)、指定された値より小さい (<)、または指定された値以下である (<=) 指定したプロパティの値を持つすべてのアイテムを検索できます。 比較する値は、定数値、またはアイテムごとの別のプロパティの値のいずれかにできます。

EWS マネージ API での関係テスト フィルター

次の例では、EWS Managed API を使用して、定数値 3 に対して指定された関係である ItemIndex プロパティの値を持つすべてのアイテムを返す検索フィルターを作成する方法を示します。

// Find all items where the custom property value is > 3.
SearchFilter.IsGreaterThan greaterThanFilter =
    new SearchFilter.IsGreaterThan(customPropDefinition, 3);
// Find all items where the custom property value is >= 3.
SearchFilter.IsGreaterThanOrEqualTo greaterThanOrEqualFilter =
    new SearchFilter.IsGreaterThanOrEqualTo(customPropDefinition, ItemSchema.Size);
// Find all items where the custom property value is < 3.
SearchFilter.IsLessThan lessThanFilter =
    new SearchFilter.IsLessThan(customPropDefinition, 3);
// Find all items where the custom property value is <= 3.
SearchFilter.IsLessThanOrEqualTo lessThanOrEqualFilter =
    new SearchFilter.IsLessThanOrEqualTo(customPropDefinition, 3);

EWS での関係テスト フィルター

次の例では、EWS を使用して、定数値 3 よりも大きい ItemIndex プロパティの値を持つすべてのアイテムを返す検索フィルターを作成する方法を示します。

<t:IsGreaterThan>
  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
  <t:FieldURIOrConstant>
    <t:Constant Value="3" />
  </t:FieldURIOrConstant>
</t:IsGreaterThan>

次の例では、定数値 3 以上の ItemIndex プロパティの値を持つすべてのアイテムを返す検索フィルターを作成する方法を示します。

<t:IsGreaterThanOrEqualTo>
  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
  <t:FieldURIOrConstant>
    <t:Constant Value="3" />
  </t:FieldURIOrConstant>
</t:IsGreaterThanOrEqualTo>

次の例では、定数値 3 よりも小さい ItemIndex プロパティの値を持つすべてのアイテムを返す検索フィルターを作成する方法を示します。

<t:IsLessThan>
  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
  <t:FieldURIOrConstant>
    <t:Constant Value="3" />
  </t:FieldURIOrConstant>
</t:IsLessThan>

次の例では、定数値 3 以下の ItemIndex プロパティの値を持つすべてのアイテムを返す検索フィルターを作成する方法を示します。

<t:IsLessThanOrEqualTo>
  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
  <t:FieldURIOrConstant>
    <t:Constant Value="3" />
  </t:FieldURIOrConstant>
</t:IsLessThanOrEqualTo>

否定フィルター

否定フィルターでは、別のフィルターを否定し、反対の検索結果を得ることができます。他のフィルターは特定の条件に一致する結果を返すのに対し、否定フィルターは、適用されるフィルターで指定した条件に一致しない結果を返します。

EWS Managed API での否定フィルター

次の例は、EWS Managed API を使用して、件名に部分文字列 "meeting notes" (会議メモ) を持たないすべてのアイテムを返す検索フィルターを作成する方法を示しています。

SearchFilter.ContainsSubstring subjectFilter = new SearchFilter.ContainsSubstring(ItemSchema.Subject,
    "meeting notes", ContainmentMode.Substring, ComparisonMode.IgnoreCase);
SearchFilter.Not subjectNotFilter =
    new SearchFilter.Not(subjectFilter);

EWS での否定フィルター

次の例は、件名に部分文字列 "meeting notes" (会議メモ) を持たないすべてのアイテムを返す検索フィルターを作成する方法を示しています。

<t:Not>
  <t:Contains ContainmentMode="ExactPhrase" ContainmentComparison="IgnoreCase">
    <t:FieldURI FieldURI="item:Subject" />
    <t:Constant Value="meeting notes" />
  </t:Contains>
</t:Not>

複合フィルター

複合フィルターでは、複数のフィルターを組み合わせてより複雑な検索条件を作成することができます。 論理演算子 AND または OR を使用して、条件を組み合わせることができます。 この方法で、「件名に ’meeting notes’ (会議メモ) が含まれている Sadie Daniels からすべてのメール」のような検索を行うことができます。

EWS マネージ API での複合フィルター

次の例では、EWS Managed API を使用して、Sadie Daniels から送信され、件名に "meeting notes" (会議メモ) を含むすべてのアイテムを返す検索フィルターを作成する方法を示しています。

SearchFilter.ContainsSubstring subjectFilter = new SearchFilter.ContainsSubstring(ItemSchema.Subject,
    "meeting notes", ContainmentMode.Substring, ComparisonMode.IgnoreCase);
EmailAddress manager = new EmailAddress("sadie@contoso.com");
SearchFilter.IsEqualTo fromManagerFilter =
    new SearchFilter.IsEqualTo(EmailMessageSchema.Sender, manager);
SearchFilter.SearchFilterCollection compoundFilter =
    new SearchFilter.SearchFilterCollection(LogicalOperator.And, subjectFilter, fromManagerFilter);

EWS での複合フィルター

次の例では、EWS を使用して、Sadie Daniels から送信され、件名に "meeting notes" (会議メモ) を含むすべてのアイテムを返す検索フィルターを作成する方法を示しています。

<t:And>
  <t:Contains ContainmentMode="Substring" ContainmentComparison="IgnoreCase">
    <t:FieldURI FieldURI="item:Subject" />
    <t:Constant Value="meeting notes" />
  </t:Contains>
  <t:IsEqualTo>
    <t:FieldURI FieldURI="message:Sender" />
    <t:FieldURIOrConstant>
      <t:Constant Value="sadie@fourthcoffee.com" />
    </t:FieldURIOrConstant>
  </t:IsEqualTo>
</t:And>

例: 検索フィルターと EWS マネージ API を使用してアイテムを検索する

次の EWS マネージ API メソッドは検索フィルターを使用します。

次の例では ExchangeService.FindItems メソッドを使用しますが、同じルールと概念がすべてのメソッドに適用されます。 この例では、SearchWithFilter というメソッドが定義されています。 パラメーターとして、ExchangeService オブジェクト、WellKnownFolderName オブジェクト、および SearchFilter オブジェクトを取ります。 この例では、ExchangeService オブジェクトは Credentials プロパティと Url プロパティの有効な値で初期化されているものとします。 SearchFilter クラスは、さまざまな検索フィルターすべての基本クラスです。

using Microsoft.Exchange.WebServices.Data
private static Guid SearchTestGUID = new Guid("{AA3DF801-4FC7-401F-BBC1-7C93D6498C2E}");
private static ExtendedPropertyDefinition customPropDefinition =
        new ExtendedPropertyDefinition(SearchTestGUID, "ItemIndex", MapiPropertyType.Integer);
static void SearchWithFilter(ExchangeService service, WellKnownFolderName folder, SearchFilter filter)
{
    // Limit the result set to 10 items.
    ItemView view = new ItemView(10);
    view.PropertySet = new PropertySet(ItemSchema.Subject, 
                                       ItemSchema.DateTimeReceived,
                                       EmailMessageSchema.IsRead,
                                       customPropDefinition);
    // Item searches do not support Deep traversal.
    view.Traversal = ItemTraversal.Shallow;
    // Sorting.
    view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
    try
    {
        FindItemsResults<Item> results = service.FindItems(folder, filter, view);
        foreach (Item item in results.Items)
        {
            Console.WriteLine("Subject: {0}", item.Subject);
            Console.WriteLine("Id: {0}", item.Id.ToString());
            if (item.ExtendedProperties.Count > 0 &&
                 item.ExtendedProperties[0].PropertyDefinition == customPropDefinition)
            {
                Console.WriteLine("Search Index: {0}", item.ExtendedProperties[0].Value);
            }
            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);
    }
}

この記事の例で示すあらゆる検索フィルターに、この関数を使用できます。この例では、複合フィルターを使用して、件名に "meeting notes" (会議メモ) がある Sadie Daniels からの受信トレイのすべてのアイテムを返します。

SearchFilter.ContainsSubstring subjectFilter = new SearchFilter.ContainsSubstring(ItemSchema.Subject,
    "meeting notes", ContainmentMode.Substring, ComparisonMode.IgnoreCase);
EmailAddress manager = new EmailAddress("sadie@contoso.com");
SearchFilter.IsEqualTo fromManagerFilter =
    new SearchFilter.IsEqualTo(EmailMessageSchema.Sender, manager);
SearchFilter.SearchFilterCollection compoundFilter =
    new SearchFilter.SearchFilterCollection(LogicalOperator.And, subjectFilter, greaterThanFilter);
SearchWithFilter(service, WellKnownFolderName.Inbox, compoundFilter);

例: 検索フィルターと EWS を使用してアイテムを検索する

次の EWS の操作は検索フィルターを使用します。

次の例では FindItem 操作を使用しますが、両方の操作で同じルールと概念が適用されます。 検索フィルターは、SOAP 要求の Restriction 要素に含まれます。 この例では、前述の EWS マネージ API の例で示している検索に相当する SOAP 要求を送信します。

<?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="message:IsRead" />
          <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:IndexedPageItemView MaxEntriesReturned="10" Offset="0" BasePoint="Beginning" />
      <m:Restriction>
        <t:And>
          <t:Contains ContainmentMode="Substring" ContainmentComparison="IgnoreCase">
            <t:FieldURI FieldURI="item:Subject" />
            <t:Constant Value="meeting notes" />
          </t:Contains>
          <t:IsEqualTo>
            <t:FieldURI FieldURI="message:Sender" />
            <t:FieldURIOrConstant>
              <t:Constant Value="sadie@contoso.com" />
            </t:FieldURIOrConstant>
          </t:IsEqualTo>
        </t:And>
      </m:Restriction>
      <m:SortOrder>
        <t:FieldOrder Order="Descending">
          <t:FieldURI FieldURI="item:DateTimeReceived" />
        </t:FieldOrder>
      </m:SortOrder>
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="inbox" />
      </m:ParentFolderIds>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

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

<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="3" TotalItemsInView="3" IncludesLastItemInRange="true">
            <t:Items>
              <t:Message>
                <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                <t:Subject>meeting notes</t:Subject>
                <t:DateTimeReceived>2013-11-20T21:18:51Z</t:DateTimeReceived>
                <t:ExtendedProperty>
                  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
                  <t:Value>5</t:Value>
                </t:ExtendedProperty>
                <t:IsRead>true</t:IsRead>
              </t:Message>
              <t:Message>
                <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                <t:Subject>Meeting Notes</t:Subject>
                <t:DateTimeReceived>2013-11-20T21:18:51Z</t:DateTimeReceived>
                <t:ExtendedProperty>
                  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
                  <t:Value>6</t:Value>
                </t:ExtendedProperty>
                <t:IsRead>true</t:IsRead>
              </t:Message>
              <t:Message>
                <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                <t:Subject>Meeting notes</t:Subject>
                <t:DateTimeReceived>2013-11-20T21:18:51Z</t:DateTimeReceived>
                <t:ExtendedProperty>
                  <t:ExtendedFieldURI PropertySetId="aa3df801-4fc7-401f-bbc1-7c93d6498c2e" PropertyName="ItemIndex" PropertyType="Integer" />
                  <t:Value>7</t:Value>
                </t:ExtendedProperty>
                <t:IsRead>true</t:IsRead>
              </t:Message>
            </t:Items>
          </m:RootFolder>
        </m:FindItemResponseMessage>
      </m:ResponseMessages>
    </m:FindItemResponse>
  </s:Body>
</s:Envelope>

次の手順

これで、基本的な検索での検索フィルターの使用に慣れ、より高度な検索テクニックに進むことができます。

関連項目