5

I have numeric fields that I want to filter on with a range, however, these need to be dynamic using the SearchResultItem's property indexer. The code I'm currently using is:

var predicate = PredicateBuilder.False<SearchResultItem>();

return predicate.Or(i => (double)i[(ObjectIndexerKey)"price"] > 20 && (double)i[(ObjectIndexerKey)"price"] <= 40);

However, this doesn't appear to be working. In the search log, I can see that the query being produced is:

+(+price:{20 TO *] +price:[* TO 39.99])

The first thing is that this looks like a syntax bug to me? There is a curly brace instead of a square bracket. Unsurprisingly Luke will not parse this:

Cannot parse '+(+price:{20 TO *] +price:[* TO 39.99])': Encountered " <RANGEEX_GOOP> "+price:[* "" at line 1, column 19. Was expecting: "}" ...

If I change the expression in Luke to:

+price:[20 TO 50]

Then it works and I get back the expected documents. How can I write the Linq to achieve the same?

UPDATE:

Figured out the syntax:

return predicate.Or(i => ((double)i[(ObjectIndexerKey)"price"]).Between(20, 40, Inclusion.Both));

Using the extension method:

Sitecore.ContentSearch.Linq.Between

This produces the following in the search log:

12136 10:14:23 INFO  ExecuteQueryAgainstLucene (sitecore_master_index): +price:[20 TO 40] - Filter : 

If I put

+price:[20 TO 40] 

Into Luke, it returns the documents I expect to see. Yet in code, no results come back?

UPDATE 2

I think I've tracked this down to this flag (which is incidentally connected to my problems on this question):

enter image description here

The legend for this flag in Luke describes it as "Indexed". This currently not set and the sort & filtering doesn't work when this is not set. I had previously got the sort working and noticed that this was set. Since rebuilding the index, it's no longer set. But I haven't changed anything so I don't know what is controlling that flag?

  • try to cast to float instead of double – Andrei Paliakou Nov 23 '17 at 11:14
  • Can you include "=" in the first predicate: (double)i[(ObjectIndexerKey)"price"] >= 20? – grg Nov 23 '17 at 11:49
10

Figured it out:

return predicate.Or(i => ((double)i[(ObjectIndexerKey)"price"]).Between(20, 40, Inclusion.Both));

Using the extension method:

Sitecore.ContentSearch.Linq.Between

The other thing I needed to do was ensure that the field is configured as TOKENIZED:

      <field fieldName="price"
         storageType="YES"
         indexType="TOKENIZED"
         vectorType="NO"
         boost="1f"
         type="System.Double" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />

This seems to ensure that flag is set in Luke which seems to determine whether sorting & filtering works on the field.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.