Search interactions

Current version: 9.2

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.

Note

Refer to the list of supported methods for xConnect search.

Search by interaction ID

Search by interaction ID is not supported. If you know the interaction ID, get the interaction from the collection database.

Search by contact ID

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

Note

This query does not require a join.

RequestResponse
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
                }
            }
        }
    }
}

Search by event definition ID

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

RequestResponse
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.

Search by event type

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

RequestResponse
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
                }
            }
        }
    }
}

Search by event property

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

RequestResponse
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
                }
            }
        }
    }
}

Search by interaction property

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

RequestResponse
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
                }
            }
        }
    }
}

Search by interaction facets

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.

RequestResponse
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
                }
            }
        }
    }
}

Results and pagination

The .GetBatchEnumerator() or .GetBatchEnumeratorSync() extension methods are the recommended way to return results from a query. See the overview of pagination 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:

RequestResponse
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

RequestResponse
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.

Expand options

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. 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.

RequestResponse
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.

Count interactions

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.

RequestResponse
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
                }
            }
        }
    }
}

Do you have some feedback for us?

If you have suggestions for improving this article,