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.
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:
This query does not require a join.
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:
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
}
}
}
}
}
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
.
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:
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:
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
.
You can use the .GetFacet<TFacet>
method or the an extension method such as .WebVisit()
if one is available.
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.
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 |
|
Recommended way of paginating results. |
|
Can be used with |
|
Can be used with |
Synchronous | |
Method |
Notes |
|
Recommended way of paginating results. |
|
Can be used with |
The following example demonstrates how to use each method to return results:
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)
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.
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
}
}
}
}
}
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.
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
}
}
}
}
}