public override Query Rewrite(IndexReader r)
{
if (!query.Clauses.Any())
{
return new MatchAllDocsQuery();
}
IList<Filter> filters = new List<Filter>();
IList<Query> queries = new List<Query>();
IList<BooleanClause> clauses = query.Clauses;
Query baseQuery;
int startIndex;
if (drillDownDims.Count == query.Clauses.Count())
{
baseQuery = new MatchAllDocsQuery();
startIndex = 0;
}
else
{
baseQuery = clauses[0].Query;
startIndex = 1;
}
for (int i = startIndex; i < clauses.Count; i++)
{
BooleanClause clause = clauses[i];
Query queryClause = clause.Query;
Filter filter = GetFilter(queryClause);
if (filter != null)
{
filters.Add(filter);
}
else
{
queries.Add(queryClause);
}
}
if (filters.Count == 0)
{
return query;
}
else
{
// Wrap all filters using FilteredQuery
// TODO: this is hackish; we need to do it because
// BooleanQuery can't be trusted to handle the
// "expensive filter" case. Really, each Filter should
// know its cost and we should take that more
// carefully into account when picking the right
// strategy/optimization:
Query wrapped;
if (queries.Count == 0)
{
wrapped = baseQuery;
}
else
{
// disable coord
BooleanQuery wrappedBQ = new BooleanQuery(true);
if ((baseQuery is MatchAllDocsQuery) == false)
{
wrappedBQ.Add(baseQuery, Occur.MUST);
}
foreach (Query q in queries)
{
wrappedBQ.Add(q, Occur.MUST);
}
wrapped = wrappedBQ;
}
foreach (Filter filter in filters)
{
wrapped = new FilteredQuery(wrapped, filter, FilteredQuery.QUERY_FIRST_FILTER_STRATEGY);
}
return wrapped;
}
}