Getting Stack Overflow when performing Linq to Sitecore Query

591 views Asked by At

I'm running into an interesting Linq to Sitecore issue. I have the case where I have a directory of people and a directory of locations that are all stored in Sitecore. I'm trying to write a search function that will allow me to search for people nearby. Adding a wrinkle to this is the fact that people can be associated with multiple locations.

So far the approach has been to find nearby locations, get their id's then find all of the people who are associated with those locations.

This looks roughly like:

var locations = GetNearbyLocations(lat, long, radius) // returns a list of short ID's 

var searchPredicate = PredicateBuilder.True<SearchResultItem>();
var locationsPredicate = PredicateBuilder.False<SearchResultItem>();

foreach (var location in locations)
{
    locationPredicate = locationPredicate.Or(x => x["location"] == location);
}

searchPredicate = searchPredicate.And(locationPredicate);
searchPredicate = searchPredicate.And(sri => sri.TemplateId == personTemplateId);

using (var context = index.CreateSearchContext())
{
    var peopleReults = context.GetQueryable<SearchResultItem>.Where(locationPredicate).GetResults();
}

The above works great if GetNearbyLocations returns a relatively small set of locations. Once we get over 150 or so, the call to GetQuerable will result in a stack overflow.

2

There are 2 answers

5
Ian Graham On

You can probably use the locations array and do a contains.

 locationPredicate.And(x=>locations.Contains(x["location"]));

If you get a big fat error from that Ill post some lambda expressions that you can use instead.

2
DougCouto On

Lucene can only handle 1024 clauses at a time.

There is a Sitecore setting called ContentSearch.LuceneQueryClauseCount that is supposed to force Lucene to accept whatever number of clauses you define in the setting but it doesn't seem to work. Changing the value of this setting doesn't seem to do anything during the search operation. There is one way to force this setting to be read and force Lucene to accept more than 1024 OR clauses at a time. Increase the value of this setting and before performing the search, run this line of code:

BooleanQuery.MaxClauseCount = int.Parse(Sitecore.Configuration.Settings.GetSetting("ContentSearch.LuceneQueryClauseCount"));

This allows you to submit a query with more than 1024 clauses, however, at some point, Lucene will still throw a StackOverflowException. To get around the Lucene limitation, you have to break up the number of OR clauses by increments of 1024 and perform multiple searches with a subset of the OR clauses each time.