1. Work with search

Supported methods and operators for xConnect search

Version:

xConnect search does not implement all of IAsyncQueryable<T> methods and throws a Sitecore.XConnect.Search.YourLinqIsTooStrongException or an XdbModelException exception if you try to use a method that is not supported. The following table applies to both contact and interaction searches unless explicitly stated.

Refer to the xConnect Client API for an overview of synchronous and asynchronous extension methods.

Extension method and operator support matrix:

Method/OperatorxConnectIAsyncQueryableNotes
.Where()YesYes
.Any()YesYesSee the Azure Search list field limitations section for restrictions.
.ToArray()YesYes
.ToList()YesYes
.Count()YesYes
.OrderBy()YesYes
.OrderByDescending()YesYes
.ThenBy()YesYes
.ThenByDescending()YesYes
.Skip()YesYesSee Paginating xConnect search results.
.Take()YesYesSee Paginating xConnect search results.
.FirstOrDefault()YesYes
.First()YesYes
.Single()YesYes
.SingleOrDefault()YesYes
== and !=YesYes
< and >YesYes
<= and >=YesYes
&& and ||YesYes
.GetBatchEnumerator()YesNo
.GetBatchEnumeratorSync()YesNo
.ToSearchResults()YesNo
.WithExpandOptions()YesNo
.AsEnumerable()YesNoSynchronous only.
ContainsNoYes
StartsWithNoYes
EndsWithNoYes
ToStringNoYes
EqualsNoYes
Note

There is no Like() extension method.

xConnect search provider limitations

xConnect search providers do not support the following scenarios:

Limitations of xConnect search providers:

  • Scenario: Limitation

  • Custom methods inside search expressions: The xConnect Client API does not support custom method calls inside LINQ query expressions. You receive a Sitecore.XConnect.Search.YourLinqIsTooStrongException or an XdbModelException exception.

  • Search for null values: It is not possible to check if a facet is null. For example:

    var notWebVisits = client.Interactions.Where(c => c.WebVisit() == null);
  • Search by Timespan in custom event properties: The following query (using a custom Timespan property) is unsupported

    can still use the default Duration property on events. This restriction only applies to events, not facets.

    var interactions = await _client.Contacts.Where(c => c.Interactions.Any(i => i.Events.OfType<CampaignEvent>().Any(e => e.CustomCampaignTimespan == TimeSpan.Zero)));
  • First, FirstOrDefault, Last, LastOrDefault, or Count inside a LINQ expression: Not supported:

    // First() inside a LINQ expression is unsupported:
    var interactions = await _client.Interactions.Where(i => i.Events.First().EngagementValue == 11).ToList();
    
    // FirstOrDefault() inside a LINQ expression is unsupported:
    var contacts = await _client.Contacts.Where(contact => contact.Interactions.OrderByDescending(x => x.StartDateTime).FirstOrDefault().WebVisit().SiteName == "value");
    
    // Last() inside a LINQ expression is unsupported:
    var contacts = await _client.Contacts.Where(contact => contact.Interactions.Last().WebVisit().SiteName == value);
  • Timespan: You cannot use Timespan with a query that combines the OfType operator AND a Timespan property (for example, Hours, Minutes, Seconds, and so on).Supported

    supported:

    events.OfType<SomeEventType>(e => e.SomeTypeTimeSpanField > TimeSpan.FromHours(2))
    events.OfType<SomeEventType>(e => e.SomeTypeTimeSpanField.Hours > 10)
  • Repeated names in paths to complex lists: The following queries are unsupported because Path.To.Nested is the same for both lists:

    i.Scores().Scores.Any(s=>s.Path.To.Nested.Any())
    i.ProfileScores().ProfileScores.Any(s=>s.Path.To.Nested.Any())

Azure Search provider limitations

The following limitations are specific to the Azure Search provider for xConnect search:

Limitations of Azure Search providers:

  • Scenario: Limitation

  • contact.Interactions.Any(): Azure Search provider does not support joins.For more information, see Work with search and Search contacts (includes examples with and without joins).ImportantThis Azure Search limitation affects which segmentation rules you can use. For example, you cannot filter contacts by email events (such as opening an email or clicking a link).

  • Partial text search: Not supported by the Azure Search provider. For example:

    client.Contacts.Where(c => c.TextMatch("Mar"))

Azure Search list field limitations

The following table relates to complex type limitations in Azure Search.

9.0 Update 2

9.0 Update 2 introduces improvements to comparisons within lists of complex types. The following shows the operator support for these types:

Azure Search list field support matrix for 9.0 Update 2:

Types==||&&!>>=<<=!=
Nested lists of strings, enums, or GuidsYesYesYesYesNoNoNoNoNo
Nested lists of complex types or other simple types such as int or floatYesYesYesYesYesYesYesYesYes

The following gives examples of operator usage for these types:

Azure Search list field examples for 9.0 Update 2:

  • Types: Examples

  • Nested lists of strings, enums, or Guids: Not supported:Supported:

    c=>c.SomeFacet().SomeList.Any(e=>e!="hello")
    c=>c.SomeFacet().SomeList.Any(e=>e!="hello"||e!="world")
    c=>c.SomeFacet().SomeList.Any(e=>e=="hello")
    c=>c.SomeFacet().SomeList.Any(e=>e=="hello"||e=="world")
  • Nested lists of complex types or other simple types such as int or float: Supported:

    c=>c.SomeFacet().SomeList.Any(e=>e.Property1>2)
    c=>c.SomeFacet().SomeList.Any(e=>e.Property1!=2)
    c=>c.SomeFacet().SomeList.Any(e=>e.Property1==2&&e.Property2=="string")
    c=>c.SomeFacet().SomeList.Any(e=>e.Property1==2||e.Property2=="string")
  • A list that contains another list: You can use a nested Any() to reach the nested list.Supported:

    someList.Any(v=>v.NestedList.Any(u=>u.SomeField==2))
  • Nested lists of strings, enums, or Guids, inside the Any() predicate: You can use == and || inside the Any() predicate.Supported:

    c=>c.SomeFacet().SomeList.Any(e=>e=="hello")
    c=>c.SomeFacet().SomeList.Any(e=>e=="hello"||e=="world")
  • The Any() that follows an OfType<T> call: It refers to fields of the exact type or the base class.Supported:

    i=>i.Events.OfType<Outcome>().Any(o=>o.MonetaryValue>10)
    i=>i.Events.OfType<Outcome>().Any(o=>o.DefinitionId==someId)

9.0 Initial Release and 9.0 Update 1

The following shows the operator support for these types:

Azure Search list field support for 9.0 Initial Release and 9.0 Update 1:

Types==||&&!>>=<<=!=
Nested lists inside the Any() predicateYesNoNoNoNoNoNoNoNo

The following gives examples of operator usage for these types:

Azure Search list field examples for 9.0 Initial Release and 9.0 Update 1:

  • Types: Examples

  • A list that contains another list: You can use a nested Any() to reach the nested list.Supported:

    someList.Any(v=>v.NestedList.Any(u=>u.SomeField==2))
  • Nested lists inside the Any() predicate: Not supported:Supported:

    c=>c.SomeFacet().SomeList.Any(e=>e.Property1>2)
    c=>c.SomeFacet().SomeList.Any(e=>e.Property1!=2)
    c=>c.SomeFacet().SomeList.Any(e=>e.Property1==2&&e.Property2=="string")
    c=>c.SomeFacet().SomeList.Any(e=>e.Property1==2||e.Property2=="string")
    MyListProperty.Any(v=>v.SomeField==2)
    c=>c.SomeFacet().SomeList.Any(e=>e.Property1==2)||
    c=>c.SomeFacet().SomeList.Any(e=>e.Property2=="string")
  • The Any() that follows an OfType<T> call: You can only refer to fields of the exact type that was specified, not the base class.Not supported

    though MonetaryValue is a property of Outcome, you cannot use Any() with >).NoteDefinitionId is a property of a base class, not of Outcome.

    i=>i.Events.OfType<Outcome>().Any(o=>o.MonetaryValue>10)
    i=>i.Events.OfType<Outcome>().Any(o=>o.DefinitionId==someId)
If you have suggestions for improving this article, let us know!