chriseldredge / Lucene.Net.Linq

LINQ provider to run native queries on a Lucene.Net index
Other
151 stars 65 forks source link

Unable to search within a nullable int field #82

Open xumix opened 9 years ago

xumix commented 9 years ago

The query looks like:

var bdates = parameter.ChildBirthDates.Select(s => s.TryParseDateYyyyMmDd().Value.GetDiffInYears(date1)).ToArray();
query = query.Where(q => (!q.ChildFromAge.HasValue || q.ChildFromAge <= bdates.Min()) && (!q.ChildToAge.HasValue || q.ChildToAge <= bdates.Max()));

So I want items where there are no limitsor the limits are in range. The error looks like this:

System.NotSupportedException occurred
  HResult=-2146233067
  Message=Expected Left or Right to be LuceneQueryFieldExpression
  Source=Lucene.Net.Linq
  StackTrace:
       at Lucene.Net.Linq.Transformation.TreeVisitors.BinaryToQueryExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression)
       at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression)
       at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression)
       at Lucene.Net.Linq.Transformation.TreeVisitors.BinaryToQueryExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression)
       at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression)
       at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression)
       at Lucene.Net.Linq.Transformation.TreeVisitors.BinaryToQueryExpressionTreeVisitor.VisitBinaryExpression(BinaryExpression expression)
       at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitExpression(Expression expression)
       at Remotion.Linq.Clauses.WhereClause.TransformExpressions(Func`2 transformation)
       at Lucene.Net.Linq.Transformation.QueryModelTransformer.VisitWhereClause(WhereClause whereClause, QueryModel queryModel, Int32 index)
       at Remotion.Linq.Clauses.WhereClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index)
       at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection`1 bodyClauses, QueryModel queryModel)
       at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)
       at Remotion.Linq.QueryModel.Accept(IQueryModelVisitor visitor)
       at Lucene.Net.Linq.LuceneQueryExecutorBase`1.PrepareQuery(QueryModel queryModel)
       at Lucene.Net.Linq.LuceneQueryExecutorBase`1.<ExecuteCollection>d__3`1.MoveNext()
       at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
       at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
       at RestChild.Booking.Logic.TourSearchService.SearchTours(SearchToursParams parameter) in c:\Projects\RestChild\RestChild.Booking.Logic\TourSearchService.cs:line 90
  InnerException: 
xumix commented 9 years ago

The expression that causes this error looks like this: ((LuceneField(ChildFromAge) != null) == False)

chriseldredge commented 9 years ago

As a work around to using HasValue which is currently not recognized, you might have some luck using == null, as in:

query = query.Where(q => (q.ChildFromAge == null || q.ChildFromAge <= bdates.Min()) && (q.ChildToAge == null || q.ChildToAge <= bdates.Max()));

Alternatively, your data model could be altered to default ChildFromAge to zero and ChildFromAge to 200 (for example). This would likely result in better query execution performance since the less-than and greater-than expressions would be reduced to a Numeric Range Query.

xumix commented 9 years ago

Thanks for the tip! I'll use it.