---
title: "Search interactions"
slug: "search-interactions"
abstract: "How to query interactions (also known as behavioral search)."
---
# Search interactions

This topic demonstrates how to query interactions (also known as behavioral search). Each example uses the the `client.GetBatchEnumerator()` / `client.GetBatchEnumeratorSync()` methods to [paginate results](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-platform/paginatingxconnect-search-results.html "Paginating xConnect search results").

> [!note]
> Refer to [the list of supported methods](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-platform/supported-methods-and-operators-for-xconnect-search.html "Supported methods and operators for xConnect search") for xConnect search.

<details>
<summary><h2>Search by interaction ID</h2></summary>

Search by interaction ID is not supported. If you know the interaction ID, [get the interaction from the collection database](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-platform/work-with-interactions.html "Work with interactions").

</details>

<details>
<summary><h2>Search by contact ID</h2></summary>

The following example demonstrates how to search for interactions by contact ID:

> [!note]
> This query does not require a join.

```csharp
using Sitecore.XConnect.Collection.Model;
using Sitecore.XConnect.Operations;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Sitecore.XConnect.Search;
using Sitecore.XConnect;
using Sitecore.Xdb.Common.Web.Synchronous;
using Sitecore.XConnect.Client;

namespace Documentation
{
    public class SearchInteractionByContactId
    {
        // Async example
        public async void ExampleAsync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    var contactID = Guid.NewGuid(); // Replace with real contact ID

                    IAsyncQueryable<Interaction> queryable = client.Interactions
                        .Where(x => x.Contact.Id == contactID);

                    var enumerator = await queryable.GetBatchEnumerator(20);

                    while (await enumerator.MoveNext())
                    {
                        var interactionBatch = enumerator.Current; // Batch of <= 20
                    }
                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        // Sync example
        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    var contactID = Guid.NewGuid(); // Replace with real contact ID

                    IAsyncQueryable<Interaction> queryable = client.Interactions
                        .Where(x => x.Contact.Id == contactID);

                    var enumerator = queryable.GetBatchEnumeratorSync(20);

                    while (enumerator.MoveNext())
                    {
                        var interactionBatch = enumerator.Current; // Batch of <= 20
                    }
                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

</details>

<details>
<summary><h2>Search by event definition ID</h2></summary>

The following example demonstrates how to search for interactions that have at least one event with the specified defintion ID:

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore.XConnect;
using Sitecore.XConnect.Client;

namespace Documentation
{
    public class SearchInteractionByEventDefinition
    {
        public async void Example()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    var someGoalId = Guid.Parse("0565e9b0-936c-4594-8cc3-5fcace3918ed"); // Replace with real goal ID

                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.Events.Any(y => y.DefinitionId == someGoalId));

                    var enumerable = await queryable.GetBatchEnumerator(20);

                    while (await enumerable.MoveNext())
                    {
                        var interactionBatch = enumerable.Current; // Batch of <= 20 interactions

                        foreach (var interaction in interactionBatch)
                        {
                            var matchingGoals = interaction.Events.OfType<Goal>().Where(x => x.DefinitionId == someGoalId).ToList();
                        }
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    var someGoalId = Guid.Parse("0565e9b0-936c-4594-8cc3-5fcace3918ed"); // Replace with real goal ID

                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.Events.Any(y => y.DefinitionId == someGoalId));

                    var enumerable = queryable.GetBatchEnumeratorSync(20);

                    while (enumerable.MoveNext())
                    {
                        var interactionBatch = enumerable.Current; // Batch of <= 20 interactions

                        foreach (var interaction in interactionBatch)
                        {
                            var matchingGoals = interaction.Events.OfType<Goal>().Where(x => x.DefinitionId == someGoalId).ToList();
                        }
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

> [!note]
> Some event models have fixed definition IDs - use the `EventDefinitionId` property rather than hard-coding a reference to the ID. For example, to search for page view events, use the `PageViewEvent.EventDefinitionId` property.

</details>

<details>
<summary><h2>Search by event type</h2></summary>

The following example demonstrates how to search by event type - for example, all events of type `Goal` or `Outcome`.

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore.XConnect;
using Sitecore.XConnect.Client;

namespace Documentation
{
    public class SearchInteractionByEventType
    {
        public async void Example()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.Events.OfType<Goal>().Any());

                    var enumerable = await queryable.GetBatchEnumerator(20);

                    while (await enumerable.MoveNext())
                    {
                        var interactionBatch = enumerable.Current; // Batch of <= 20 interactions

                        foreach (var interaction in interactionBatch)
                        {
                            var matchingGoals = interaction.Events.OfType<Goal>();
                        }
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.Events.OfType<Goal>().Any());

                    var enumerable = queryable.GetBatchEnumeratorSync(20);

                    while (enumerable.MoveNext())
                    {
                        var interactionBatch = enumerable.Current; // Batch of <= 20 interactions

                        foreach (var interaction in interactionBatch)
                        {
                            var matchingGoals = interaction.Events.OfType<Goal>();
                        }
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

</details>

<details>
<summary><h2>Search by event property</h2></summary>

The following example demonstrates how to search for interactions using the properties of an event such as an outcome:

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore.XConnect;
using Sitecore.XConnect.Client;

namespace Documentation
{
    public class SearchInteractionByEventTypeProperty
    {
        public async void Example()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.Events.OfType<Outcome>().Any(f => f.MonetaryValue > 100.00m && f.CurrencyCode == "DKK"));

                    var enumerable = await queryable.GetBatchEnumerator(20);

                    while (await enumerable.MoveNext())
                    {
                        var interactionBatch = enumerable.Current; // Batch of <= 20 interactions

                        foreach (var interaction in interactionBatch)
                        {
                            var matchingOutcomes = interaction.Events.OfType<Outcome>();
                        }
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.Events.OfType<Outcome>().Any(f => f.MonetaryValue > 100.00m && f.CurrencyCode == "DKK"));

                    var enumerable = queryable.GetBatchEnumeratorSync(20);

                    while (enumerable.MoveNext())
                    {
                        var interactionBatch = enumerable.Current; // Batch of <= 20 interactions

                        foreach (var interaction in interactionBatch)
                        {
                            var matchingOutcomes = interaction.Events.OfType<Outcome>();
                        }
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

</details>

<details>
<summary><h2>Search by interaction property</h2></summary>

The following query returns all interactions with a `ChannelId` of `0565e9b0-936c-4594-8cc3-5fcace3918ed` that are less than ten days old:

```csharp
using Sitecore.XConnect.Collection.Model;
using Sitecore.XConnect.Operations;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Sitecore.XConnect.Search;
using Sitecore.XConnect;
using Sitecore.XConnect.Client;

namespace Documentation
{
    public class SearchInteractionProperty
    {
        // Async example
        public async void ExampleAsync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    var someChannelId = Guid.Parse("0565e9b0-936c-4594-8cc3-5fcace3918ed");

                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.ChannelId == someChannelId && x.StartDateTime > DateTime.UtcNow.AddDays(-10));

                    var enumerable = await queryable.GetBatchEnumerator(10);

                    while (await enumerable.MoveNext())
                    {
                        IReadOnlyCollection<Interaction> currentBatch = enumerable.Current;
                    }
                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        // Sync example
        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    var someChannelId = Guid.Parse("0565e9b0-936c-4594-8cc3-5fcace3918ed");

                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.ChannelId == someChannelId && x.StartDateTime > DateTime.UtcNow.AddDays(-10));

                    var enumerable = queryable.GetBatchEnumeratorSync(10);

                    while (enumerable.MoveNext())
                    {
                        IReadOnlyCollection<Interaction> currentBatch = enumerable.Current;
                    }
                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

</details>

<details>
<summary><h2>Search by interaction facets</h2></summary>

The following example demonstrates how to search by interaction facets, such as `IpInfo` and `WebVisit`.

> [!note]
> You can use the `.GetFacet<TFacet>` method or the an extension method such as `.WebVisit()` if one is available.

```csharp
using Sitecore.XConnect.Collection.Model;
using Sitecore.XConnect.Operations;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Sitecore.XConnect.Search;
using Sitecore.XConnect;
using Sitecore.XConnect.Client;

namespace Documentation
{
    public class SearchInteractionFacet
    {
        public async void ExampleAsync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.GetFacet<WebVisit>(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome" &&
                        x.IpInfo().Country == "Denmark");

                    var enumerable = await queryable.GetBatchEnumerator(20);

                    while (await enumerable.MoveNext())
                    {
                        var interactionsBatch = enumerable.Current; // Batch of 20 interactions
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.GetFacet<WebVisit>(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome" &&
                        x.IpInfo().Country == "Denmark");

                    var enumerable = queryable.GetBatchEnumeratorSync(20);

                    while (enumerable.MoveNext())
                    {
                        var interactionsBatch = enumerable.Current; // Batch of 20 interactions
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

</details>

<details>
<summary><h2>Results and pagination</h2></summary>

The `.GetBatchEnumerator()` or `.GetBatchEnumeratorSync()` extension methods are the recommended way to return results from a query. See the [overview of pagination](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-platform/paginatingxconnect-search-results.html "Paginating xConnect search results") for more information.

> [!important]
> For each method, the maximum size of a single batch is hardcoded to `Sitecore.XConnect.SearchExtensions.DefaultBatchSize`, which is set to 1000. This value is currently not configurable.

| **Synchronous** |  |
| --- | --- |
| Method | Notes |
| `awaitclient.GetBatchEnumerator()` | Recommended way of paginating results. |
| `awaitclient.ToSearchResults()` | Can be used with `Skip()` and `Take()` to control batch size. Returns a count of total results. |
| `awaitclient.ToList()` | Can be used with `Skip()` and `Take()`. Returns list of contacts. |

| **Synchronous** |  |
| --- | --- |
| Method | Notes |
| `client.GetBatchEnumeratorSync()` | Recommended way of paginating results. |
| `awaitclient.AsEnumerable()` | Can be used with `Skip()` and `Take()`. Returns IEnumerable<Contact>. |

The following example demonstrates how to use each method to return results:

```csharp
using Sitecore.XConnect.Collection.Model;
using System.Collections.Generic;
using System.Linq;
using Sitecore.XConnect;
using Sitecore.XConnect.Client;

namespace Documentation
{
    public class SearchResultsInteractions
    {
        // Async example
        public async void ExampleAsync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions.Where(c => c.GetFacet<Sitecore.XConnect.Collection.Model.PersonalInformation>(CollectionModel.FacetKeys.PersonalInformation).FirstName == "Myrtle");

                    // Option #1 - .ToSearchResults()
                    SearchResults<Sitecore.XConnect.Interaction> resultsOne = await queryable.ToSearchResults();

                    var totalResults = resultsOne.Count; // Total results
                    var interactions = resultsOne.Results.Select(x => x.Item); // Interactions
                    var something = resultsOne.Results.Select(x => x.Score); // Scores

                    // Option #2 - .ToSearchResults() with Skip()/Take()
                    SearchResults<Sitecore.XConnect.Interaction> resultsTwo = await queryable.Skip(10).Take(20).ToSearchResults();

                    var totalResultsTwo = resultsTwo.Count; // Total results
                    var interactionsTwo = resultsTwo.Results.Select(x => x.Item); // Interactions - will be 20
                    var scoresTwo = resultsTwo.Results.Select(x => x.Score); // Scores

                    // Option #3 - .GetBatchEnumerator()
                    var resultsThree = await queryable.GetBatchEnumerator(10);
                    var totalResultsThree = resultsThree.TotalCount; // Count

                    while (await resultsThree.MoveNext())
                    {
                        var interactionsThree = resultsThree.Current; // Interactions
                    }

                    // Option #4 - .ToList()
                    var resultsFour = await queryable.ToList();

                    var interactionsFour = resultsFour; // Interactions

                    // Option #5 - .ToList() with Skip()/Take()
                    var resultsFive = await queryable.Skip(10).Take(20).ToList();

                    var interactionsFive = resultsFive; // Interactions
                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        // Async example
        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Interaction> queryable = client.Interactions.Where(c => c.GetFacet<Sitecore.XConnect.Collection.Model.PersonalInformation>(CollectionModel.FacetKeys.PersonalInformation).FirstName == "Myrtle");

                    // Option #1
                    // .ToSearchResults() not available as sync extension

                    // Option #2
                    // .ToSearchResults() not available as sync extension

                    // Option #3 - .GetBatchEnumerator()
                    var resultsThree = queryable.GetBatchEnumeratorSync(10);
                    var totalResultsThree = resultsThree.TotalCount; // Count

                    while (resultsThree.MoveNext())
                    {
                        var interactionsThree = resultsThree.Current; // Interactions
                    }

                    // Option #4 - Can be used with :code:`Skip()` and :code:`Take()`
                    var resultsFour = queryable.AsEnumerable();

                    var interactionsFour = resultsFour; // Interactions

                    // Option #5 - .ToEnumerable() with Skip()/Take()
                    var resultsFive = queryable.Skip(10).Take(20).AsEnumerable();

                    var interactionsFive = resultsFive; // Interactions
                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

### Ordering results

You can orders results by an interaction’s facets or properties. The following example demonstrates how to order interactions by `StartDateTime`

```

IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
    .OrderByDescending(x => x.StartDateTime)

```

> [!note]
> You cannot order by the properties of a list. For example, you cannot order interactions by the `StartDateTime` properties of its events.

</details>

<details>
<summary><h2>Expand options</h2></summary>

Use the `.WithExpandOptions()` method to specify which interaction facets and contact facets should be returned with each interaction. These expand options are identical to the ones that you use when [retrieving a interaction by ID](https://doc.sitecore.com/xp/en/developers/93/sitecore-experience-platform/expand-related-contact.html "Expand related contact"). If you do not specify any expand options, no facets will be returned.

The following example demonstrates how to return the `WebVisit` with each interaction, as well as the `PersonalInformation` contact facet if it is available.

```csharp
using Sitecore.XConnect.Collection.Model;
using Sitecore.XConnect.Operations;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using Sitecore.XConnect.Search;
using Sitecore.XConnect;
using Sitecore.XConnect.Client;

namespace Documentation
{
    public class SearchInteractionExpandOptions
    {
        public async void ExampleAsync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.GetFacet<WebVisit>(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome")
                        .WithExpandOptions(new InteractionExpandOptions(CollectionModel.FacetKeys.WebVisit)
                        {
                            Contact = new RelatedContactExpandOptions(PersonalInformation.DefaultFacetKey)
                        });

                    var enumerable = await queryable.GetBatchEnumerator(20);

                    while (await enumerable.MoveNext())
                    {
                        var currentBatch = enumerable.Current;

                        foreach (var interaction in currentBatch)
                        {
                            var contact = interaction.Contact as Contact; // Cast IEntityReference<Contact> to Contact
                            var personalInfo = contact.Personal();

                            var interactionFacet = interaction.WebVisit();
                        }
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions
                        .Where(x => x.GetFacet<WebVisit>(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome")
                        .WithExpandOptions(new InteractionExpandOptions(CollectionModel.FacetKeys.WebVisit)
                        {
                            Contact = new RelatedContactExpandOptions(PersonalInformation.DefaultFacetKey)
                        });

                    var enumerable = queryable.GetBatchEnumeratorSync(20);

                    while (enumerable.MoveNext())
                    {
                        var currentBatch = enumerable.Current;

                        foreach (var interaction in currentBatch)
                        {
                            var contact = interaction.Contact as Contact; // Cast IEntityReference<Contact> to Contact
                            var personalInfo = contact.Personal();

                            var interactionFacet = interaction.WebVisit();
                        }
                    }

                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

> [!note]
> The related contact’s `Interactions` property will always be null - you can only expand contact facets when performing an interaction search.

</details>

<details>
<summary><h2>Count interactions</h2></summary>

The following example demonstrates how to return a count of matching interactions. This method only returns the count, no results are sent over the wire.

```csharp
using System.Linq;
using Sitecore.XConnect;
using System;

namespace Documentation
{
    public class SearchResultsWithCountInteractions
    {
        // Async example
        public async void Example()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    var count = await client.Interactions.Where(c => c.StartDateTime > DateTime.UtcNow.AddDays(-10)).Count();
                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }

        // Sync example
        public void ExampleSync()
        {
            using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
            {
                try
                {
                    // There is no synchronous extension for Count - use SuspendContextLock instead
                    int count = Sitecore.XConnect.Client.XConnectSynchronousExtensions.SuspendContextLock(client.Interactions.Where(c => c.StartDateTime > DateTime.UtcNow.AddDays(-10)).Count);
                }
                catch (XdbExecutionException ex)
                {
                    // Handle exception
                }
            }
        }
    }
}

```

</details>