Cannot parse '( AND) AND': Encountered " <AND> "AND "" at line 1, column 2.....
Here's a simplified example of what I'm trying to do (in my real code I build the expression tree by nested foreaching over collections of search terms):
If I call FilterLiteral everything works like a charm, however calling FilterDynamic (which should yield the exact same result) causes the Lucene error mentioned above. Apparently Lucene has problems translating the InvocationExpression generated by calling the dynamic Func<LogMessage, string, bool> filterMethod.
public class LogMessages_Index : AbstractIndexCreationTask<LogMessage>
{
public LogMessages_Index()
{
Map = logMessages => logMessages.Select(
lm => new
{
lm.ApplicationName,
lm.TimeStamp
});
Analyzers.Add(lm => lm.ApplicationName, typeof(StandardAnalyzer).AssemblyQualifiedName);
}
}
public class Query
{
private IDocumentStore documentStore;
public Query(IDocumentStore documentStore)
{
this.documentStore = documentStore;
}
public LogMessage[] FilterDynamic()
{
using (IDocumentSession session = documentStore.OpenSession())
{
IRavenQueryable<LogMessage> query = session.Query<LogMessage, LogMessages_BasicIndex>();
query = BuildQuery(query, (message, s) => message.ApplicationName.StartsWith(s));
List<LogMessage> logMessages = query.OrderByDescending(lm => lm.TimeStamp).ToList();
Debug.WriteLine(string.Format("Found {0} matching logmessages", logMessages.Count));
return logMessages.ToArray();
}
}
private static IRavenQueryable<LogMessage> BuildQuery(IRavenQueryable<LogMessage> query, Func<LogMessage, string, bool> filterMethod)
{
Expression<Func<LogMessage, bool>> subWhereClause = null;
Expression<Func<LogMessage, bool>> expression11 = lm => filterMethod(lm, "SDS");
subWhereClause = expression11;
Expression<Func<LogMessage, bool>> expression12 = lm => filterMethod(lm, "Que");
subWhereClause = Expression.Lambda<Func<LogMessage, bool>>(Expression<Func<LogMessage, bool>>.AndAlso(subWhereClause.Body, expression12.Body), subWhereClause.Parameters);
Expression<Func<LogMessage, bool>> expression13 = lm => filterMethod(lm, "Serv");
subWhereClause = Expression.Lambda<Func<LogMessage, bool>>(Expression<Func<LogMessage, bool>>.AndAlso(subWhereClause.Body, expression13.Body), subWhereClause.Parameters);
query = query.Where(subWhereClause);
return query;
}
public LogMessage[] FilterLiteral()
{
using (IDocumentSession session = documentStore.OpenSession())
{
IRavenQueryable<LogMessage> query = session.Query<LogMessage, LogMessages_BasicIndex>();
query = BuildLiteralQuery(query);
List<LogMessage> logMessages = query.OrderByDescending(lm => lm.TimeStamp).ToList();
Debug.WriteLine(string.Format("Found {0} matching logmessages", logMessages.Count));
return logMessages.ToArray();
}
}
private static IRavenQueryable<LogMessage> BuildLiteralQuery(IRavenQueryable<LogMessage> query)
{
Expression<Func<LogMessage, bool>> subWhereClause = null;
Expression<Func<LogMessage, bool>> expression11 = lm => lm.ApplicationName.StartsWith("SDS");
subWhereClause = expression11;
Expression<Func<LogMessage, bool>> expression12 = lm => lm.ApplicationName.StartsWith("Quer");
subWhereClause = Expression.Lambda<Func<LogMessage, bool>>(Expression<Func<LogMessage, bool>>.AndAlso(subWhereClause.Body, expression12.Body), subWhereClause.Parameters);
Expression<Func<LogMessage, bool>> expression13 = lm => lm.ApplicationName.StartsWith("Serv");
subWhereClause = Expression.Lambda<Func<LogMessage, bool>>(Expression<Func<LogMessage, bool>>.AndAlso(subWhereClause.Body, expression13.Body), subWhereClause.Parameters);
query = query.Where(subWhereClause);
return query;
}
}