Searching contacts by email with XConnect in Sitecore 9

Reading Time: 2 minutes

XConnect has been introduced in Sitecore 9 to simplify communication between applications and xDB. It has really cool API and can help create true omnichannel gathering / reading of data. Therefore you are not finally storing only “web” interactions but theoretically anything for each contact.

By default XConnect has lots of features which support GDPR adoption in solutions and help developers make solutions GDPR complaint. Sneak peak – Some follow up blog posts will come in future 😉


One of the XConnect features is contact and interaction facets which support storing Personal Identifiable Information (PII). There is a small discrepancy between Personal Identifiable Information (term mostly used in US ) and Personal Data (term used in EU and especially for GDPR). In short, Personal Data term covers broader range of data / information types so it is more restrictive.

When you try to search contacts by email or other sensitive information with XConnect, OOTB it won’t work. This is expected behavior but a bit confusing for developers.

Sample code:

using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient())
                    IAsyncQueryable<Sitecore.XConnect.Contact> queryable = client.Contacts
                        .Where(c => c.GetFacet<EmailAddressList>(EmailAddressList.DefaultFacetKey).PreferredEmail.SmtpAddress == "")
                        .WithExpandOptions(new ContactExpandOptions(EmailAddressList.DefaultFacetKey));

                    var enumerator = queryable.GetBatchEnumeratorSync(10);

                    while (enumerator.MoveNext())
                        foreach (var contact in enumerator.Current)
                            var mail = contact.Emails().PreferredEmail.SmtpAddress;
                catch (XdbExecutionException ex)
                    // Handle exception


This won’t give you expected results and enumerator will be empty.

Reason is that these facets are decorated with attribute [PIISensitive]. This means that they are storing personal sensitive data. If technically speaking, this means that they are not indexed and therefore not searchable.

Facet definition for email looks like this:

 public string SmtpAddress { get; set; }


In order to enable searching by these sensitive information, you need to enable indexing of these kind of facets (decorated with [PIISensitive] facet).

You need to set “true” in IndexPIISensitiveData setting in XConnect SearchIndexer settings.

You need to rebuild xDB search index afterwards to make changes visible and therefore email facet searchable.

More information about this can be found in awesome official XConnect documentation.

This solution is obviously not usable in scenario where you want to be complaint with GDPR so think twice about this before doing it! You need to have consent from contacts for this kind of processing.

I am still searching for solution that wouldn’t violate this.

One possible option would be to only search in email facet for contacts that gave you consent for processing BUT how would you make indexing work then? Some contact facets indexed, some not… Really complex change of the guts of XConnect and indexing. Also how about contacts that won’t give you consent? They will be invisible during search…


Happy coding!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.