Compartilhar via


Executar pesquisas agrupadas usando o EWS no Exchange

Descubra como executar pesquisas agrupadas em sua API Gerenciada do EWS ou aplicativo EWS que tem como destino o Exchange.

As pesquisas agrupadas são úteis na forma como os resultados da pesquisa são organizados. Os resultados da pesquisa organizada podem facilitar o processo de resultados do aplicativo ou exibi-los a um usuário final de maneira gerenciável.

O agrupamento funciona colocando todos os itens dentro do conjunto de resultados que têm o mesmo valor de um campo específico em um grupo. Por exemplo, você pode agrupar seus resultados pelo remetente e todos os itens da mesma pessoa estarão em um grupo separado e os itens dentro de cada grupo serão classificados de acordo com a ordem especificada na exibição. Os próprios grupos são classificados por um valor agregado com base em um campo escolhido.

Tabela 1. Métodos de API Gerenciada do EWS e operações EWS para organizar resultados de pesquisa

Se você quiser... Na API Gerenciada do EWS, use... No EWS, use...
Organizar itens com o mesmo valor em uma propriedade específica em seus resultados em grupos
Grouping.GroupOn
Elemento FieldURI como filho do elemento GroupBy
Classificar itens em cada grupo pelo valor em uma propriedade específica
ItemView.OrderBy
Elemento SortOrder
Classificar os grupos
Grouping.AggregateOn

Grouping.AggregateType

Grouping.SortDirection
Elemento FieldURI como filho do elemento AggregateOn

Atributo agregado no elemento AggregateOn

Atributo order no elemento GroupBy

Vamos dar um passo a passo.

Agrupar resultados por uma propriedade específica

A primeira etapa para usar o agrupamento é selecionar uma propriedade ou atributo nos itens no repositório exchange para agrupar. A API Gerenciada do EWS expõe-as como propriedades de classe nas classes correspondentes, enquanto o EWS as expõe como elementos XML. Você pode escolher qualquer propriedade, incluindo propriedades personalizadas ou estendidas, mas é útil entender como os itens são agrupados com base no valor da propriedade escolhida.

Todos os itens que têm o mesmo valor na propriedade que você escolher agrupar serão agrupados. Isso pode parecer óbvio, mas é um detalhe importante. Considere o que acontece se você agrupar por uma propriedade date/time, como Item.DateTimeReceived na API Gerenciada do EWS ou o elemento DateTimeReceived no EWS. A intenção pode ser organizar os resultados em grupos, com cada grupo contendo itens do mesmo dia. No entanto, o agrupamento analisa todo o valor, que inclui a hora.

O resultado final é que os itens serão agrupados para que os itens recebidos ao mesmo tempo, até o segundo, estejam em seus próprios grupos. Os resultados provavelmente serão classificados em um grande número de grupos com um pequeno número de itens em cada grupo.

Para obter um conjunto de resultados com um número menor de grupos e um número maior de itens em cada grupo, escolha uma propriedade que provavelmente terá um número menor de valores, como EmailMessage.From ou Item.Categories na API Gerenciada do EWS ou De ou Categorias no EWS. A figura a seguir mostra uma lista de emails que aparecem em uma caixa de entrada.

Figura 1. Mensagens em uma caixa de entrada

A sample list of messages in a user's Inbox.

Se você agrupar os itens na Figura 1 pela propriedade EmailMessage.From , o resultado será dois grupos, um para mensagens enviadas por Hope Gross e um para mensagens enviadas por Sadie Daniels.

Figura 2. Mensagens separadas em grupos com base na propriedade From

An image that shows messages sorted into two lists by the From property.

Classificar os itens dentro de grupos

Você pode controlar como os itens são classificados em cada grupo usando a propriedade ItemView.OrderBy na API Gerenciada do EWS ou o elemento SortOrder no EWS. A mesma ordenação se aplica a cada grupo. Por exemplo, se você classificar os itens da Figura 1 pela propriedade Item.DateTimeReceived , em ordem decrescente, o item recebido mais recentemente de Hope Gross será o primeiro no grupo Hope Gross, e o item recebido mais recentemente de Sadie Daniels será o primeiro no grupo Sadie Daniels. Convenientemente, os grupos na Figura 2 já estão classificados dessa forma.

Classificar os grupos

Agora que você tem seus grupos resolvidos, a etapa final é classificar os próprios grupos. Como os próprios grupos não têm valores específicos, o processo de agrupamento precisa atribuir um valor de classificação a cada grupo. Isso é feito por agregação dos valores de uma propriedade específica em cada grupo, especificada pela propriedade Grouping.AggregateOn na API Gerenciada do EWS ou pelo elemento FieldURI como filho do elemento AggregateOn no EWS. A propriedade Grouping.AggregateType na API Gerenciada do EWS (ou o atributo Aggregateon no elemento AggregateOn no EWS) especifica qual valor dos itens dentro de cada grupo é atribuído ao valor de classificação para o grupo – o maior valor ou o menor valor. Por fim, a ordem de classificação (decrescente ou crescente) é especificada pela propriedade Grouping.SortDirection na API Gerenciada do EWS ou pelo atributo Order no elemento GroupBy no EWS.

Por exemplo, se os grupos da Figura 2 forem classificados agregando na propriedade Item.DateTimeReceived , usando o menor valor e classificando em ordem decrescente, os itens serão retornados na ordem na Figura 3 mostrada.

Figura 3. Resultados da pesquisa agrupada com os grupos classificados pela propriedade DateTimeReceived

An image that shows a sorted lists of messages, grouped by the From property, with the groups sorted by the smallest received date/time.

As próximas seções mostram como você pode agrupar e classificar em código.

Exemplo: executar uma pesquisa agrupada usando a API Gerenciada do EWS

Os seguintes métodos de API Gerenciada do EWS podem usar o agrupamento:

O exemplo a seguir usa o método ExchangeService.FindItems ; no entanto, as mesmas regras e conceitos se aplicam ao método Folder.FindItems . Neste exemplo, um método chamado GroupItemsByFrom é definido. Ele usa um objeto ExchangeService e um objeto WellKnownFolderName como parâmetros. Ele solicita os primeiros 50 itens na pasta, agrupados pela propriedade EmailMessage.From , classificada pela propriedade Item.DateTimeReceived em ordem decrescente. Os grupos em si são classificados pelo menor valor de propriedade Item.DateTimeReceived em seus itens, em ordem decrescente.

Este exemplo supõe que o objeto ExchangeService tenha sido inicializado com valores válidos nas propriedades Credentials e URL.

static void GroupItemsByFrom(ExchangeService service, WellKnownFolderName folder)
{
    // Limit the result set to 50 items.
    ItemView view = new ItemView(50);
    view.PropertySet = new PropertySet(ItemSchema.Subject,
                                       ItemSchema.DateTimeReceived,
                                       EmailMessageSchema.From,
                                       ItemSchema.Categories);
    // Item searches do not support Deep traversal.
    view.Traversal = ItemTraversal.Shallow;
    // Specify the sorting done within the groups.
    view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
    // Configure grouping.
    Grouping groupByFrom = new Grouping();
    groupByFrom.GroupOn = EmailMessageSchema.From;
    groupByFrom.AggregateOn = ItemSchema.DateTimeReceived;
    groupByFrom.AggregateType = AggregateType.Minimum;
    groupByFrom.SortDirection = SortDirection.Descending;
    try
    {
        GroupedFindItemsResults<Item> results = service.FindItems(folder,
            view, groupByFrom);
        foreach (ItemGroup<Item> group in results.ItemGroups)
        {
            Console.WriteLine("Group: {0}", group.GroupIndex);
            foreach (Item item in group.Items)
            {
                if (item is EmailMessage)
                {
                    EmailMessage message = item as EmailMessage;
                    Console.WriteLine("From: {0}", message.From);
                    Console.WriteLine("Subject: {0}", message.Subject);
                    Console.WriteLine("Id: {0}\n", message.Id.ToString());
                }
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception while enumerating results: {0}", ex.Message);
    }
}

Exemplo: executar uma pesquisa agrupada usando o EWS

O exemplo de solicitação a seguir mostra uma solicitação de operação FindItem para os primeiros 50 itens da pasta, agrupados pelo elemento From , classificado pelo elemento DateTimeReceived em ordem decrescente. Os grupos em si são classificados pelo menor valor de elemento DateTimeReceived em seus itens, em ordem decrescente.

<?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="Exchange2007_SP1" />
    <t:TimeZoneContext>
      <t:TimeZoneDefinition Id="Eastern Standard Time" />
    </t:TimeZoneContext>
  </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:From" />
          <t:FieldURI FieldURI="item:Categories" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:IndexedPageItemView MaxEntriesReturned="50" Offset="0" BasePoint="Beginning" />
      <m:GroupBy Order="Descending">
        <t:FieldURI FieldURI="message:From" />
        <t:AggregateOn Aggregate="Minimum">
          <t:FieldURI FieldURI="item:DateTimeReceived" />
        </t:AggregateOn>
      </m:GroupBy>
      <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>

O servidor retorna a resposta a seguir.

<?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="10" TotalItemsInView="8" IncludesLastItemInRange="true">
            <t:Groups>
              <t:GroupedItems>
                <t:GroupIndex>0</t:GroupIndex>
                <t:Items>
                  <t:Message>
                    <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                    <t:Subject>Planning resources</t:Subject>
                    <t:DateTimeReceived>2013-12-10T17:41:05Z</t:DateTimeReceived>
                    <t:From>
                      <t:Mailbox>
                        <t:Name>Sadie Daniels</t:Name>
                        <t:EmailAddress>/O=FIRST ORGANIZATION/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=8D84A3F4CBB34D48838A3AECF99795C0-SADIE</t:EmailAddress>
                        <t:RoutingType>EX</t:RoutingType>
                      </t:Mailbox>
                    </t:From>
                  </t:Message>
                  <t:Message>
                    <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                    <t:Subject>Timeline</t:Subject>
                    <t:DateTimeReceived>2013-12-10T17:40:37Z</t:DateTimeReceived>
                    <t:Categories>
                      <t:String>Project</t:String>
                    </t:Categories>
                    <t:From>
                      <t:Mailbox>
                        <t:Name>Sadie Daniels</t:Name>
                        <t:EmailAddress>/O=FIRST ORGANIZATION/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=8D84A3F4CBB34D48838A3AECF99795C0-SADIE</t:EmailAddress>
                        <t:RoutingType>EX</t:RoutingType>
                      </t:Mailbox>
                    </t:From>
                  </t:Message>
                  <t:Message>
                    <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                    <t:Subject>For your perusal</t:Subject>
                    <t:DateTimeReceived>2013-11-20T21:51:16Z</t:DateTimeReceived>
                    <t:From>
                      <t:Mailbox>
                        <t:Name>Sadie Daniels</t:Name>
                        <t:EmailAddress>/O=FIRST ORGANIZATION/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=8D84A3F4CBB34D48838A3AECF99795C0-SADIE</t:EmailAddress>
                        <t:RoutingType>EX</t:RoutingType>
                      </t:Mailbox>
                    </t:From>
                  </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:Categories>
                      <t:String>Blue category</t:String>
                    </t:Categories>
                    <t:From>
                      <t:Mailbox>
                        <t:Name>Sadie Daniels</t:Name>
                        <t:EmailAddress>/O=FIRST ORGANIZATION/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=8D84A3F4CBB34D48838A3AECF99795C0-SADIE</t:EmailAddress>
                        <t:RoutingType>EX</t:RoutingType>
                      </t:Mailbox>
                    </t:From>
                  </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:From>
                      <t:Mailbox>
                        <t:Name>Sadie Daniels</t:Name>
                        <t:EmailAddress>/O=FIRST ORGANIZATION/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=8D84A3F4CBB34D48838A3AECF99795C0-SADIE</t:EmailAddress>
                        <t:RoutingType>EX</t:RoutingType>
                      </t:Mailbox>
                    </t:From>
                  </t:Message>
                </t:Items>
              </t:GroupedItems>
              <t:GroupedItems>
                <t:GroupIndex>1</t:GroupIndex>
                <t:Items>
                  <t:Message>
                    <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                    <t:Subject>Query</t:Subject>
                    <t:DateTimeReceived>2013-12-10T17:43:15Z</t:DateTimeReceived>
                    <t:From>
                      <t:Mailbox>
                        <t:Name>Hope Gross</t:Name>
                        <t:EmailAddress>/O=FIRST ORGANIZATION/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=9B55E4100C064D9D8C5F72FF36802ED3-HOPE</t:EmailAddress>
                        <t:RoutingType>EX</t:RoutingType>
                      </t:Mailbox>
                    </t:From>
                  </t:Message>
                  <t:Message>
                    <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                    <t:Subject>Update</t:Subject>
                    <t:DateTimeReceived>2013-12-10T17:42:33Z</t:DateTimeReceived>
                    <t:Categories>
                      <t:String>Project</t:String>
                      <t:String>Blue category</t:String>
                    </t:Categories>
                    <t:From>
                      <t:Mailbox>
                        <t:Name>Hope Gross</t:Name>
                        <t:EmailAddress>/O=FIRST ORGANIZATION/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=9B55E4100C064D9D8C5F72FF36802ED3-HOPE</t:EmailAddress>
                        <t:RoutingType>EX</t:RoutingType>
                      </t:Mailbox>
                    </t:From>
                  </t:Message>
                  <t:Message>
                    <t:ItemId Id="AAMkAGM2..." ChangeKey="CQAAABYA..." />
                    <t:Subject>This cat is hilarious!</t:Subject>
                    <t:DateTimeReceived>2013-10-15T20:22:12Z</t:DateTimeReceived>
                    <t:From>
                      <t:Mailbox>
                        <t:Name>Hope Gross</t:Name>
                        <t:EmailAddress>/O=FIRST ORGANIZATION/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=9B55E4100C064D9D8C5F72FF36802ED3-HOPE</t:EmailAddress>
                        <t:RoutingType>EX</t:RoutingType>
                      </t:Mailbox>
                    </t:From>
                  </t:Message>
                </t:Items>
              </t:GroupedItems>
            </t:Groups>
          </m:RootFolder>
        </m:FindItemResponseMessage>
      </m:ResponseMessages>
    </m:FindItemResponse>
  </s:Body>
</s:Envelope>

Diferenças de versão

Versões do Exchange começando com a versão principal 15 e terminando com elementos de grupo de retorno build 15.0.775.38 (do tipo GroupedItemsType) no lugar de elementos GroupedItems na resposta SOAP. Se você estiver usando a API Gerenciada do EWS, isso fará com que a coleção GroupedFindItemsResults.ItemGroups contenha 0 objetos. Se você estiver usando o EWS, os elementos group devem ser tratados como elementos GroupedItems .

As versões do Exchange começando com a versão principal 15 retornam elementos de Grupo ou GroupedItems extras com o atributo xsi:nil definido como true na resposta SOAP. Se você estiver usando a API Gerenciada do EWS, esses elementos extras farão com que um ServiceXmlDeserializationException seja lançado. Se você estiver usando o EWS, esses elementos extras devem ser ignorados.

Confira também