In case anyone is interested and has a similar requirement, here's how I solved this problem (source below):

Usage:

   var parser = new QueryParser("fulltext", new StandardAnalyzer());
   parser.SetDefaultOperator(QueryParser.Operator.AND);
   var searchQuery = parser.Parse("car");

   var softBooleanQuery = new SoftBooleanQuery();
   var visibleQuery = new SoftTermQuery(new Term("visible", "1"));

   softBooleanQuery.Add(searchQuery, BooleanClause.Occur.MUST);
   softBooleanQuery.Add(visibleQuery, BooleanClause.Occur.MUST);

   ... search with softBooleanQuery ...
Helper classes:

   public class SoftBooleanQuery : BooleanQuery
   {
       public override Query Rewrite(IndexReader reader)
       {
           restart:
           foreach (BooleanClause clause in Clauses())
           {
               var softQuery = clause.GetQuery() as SoftTermQuery;
               if (softQuery != null)
               {
                   if (softQuery.Rewrite(reader) == null)
                   {
// rewritten query is null, remove it from the clauses (see SoftTermQuery.Rewrite)
                       Clauses().Remove(clause);
                       goto restart;
                   }
               }
}
           return base.Rewrite(reader);
       }
   }

   public class SoftTermQuery : TermQuery
   {
       public SoftTermQuery(Term t) : base(t)
       {
       }

       public static bool IsTermIndexed(IndexReader reader, Term t)
       {
           return reader.Terms(t).Term().Field() == t.Field();
       }

       public override Query Rewrite(IndexReader reader)
       {
           Term t = GetTerm();
           // if the term does not exist in this IndexReader, return null
           return IsTermIndexed(reader, t) ? base.Rewrite(reader) : null;
       }

       public override string ToString(string field)
       {
           return base.ToString(field);
       }
   }



Andrew C. Smith wrote:
Maybe you can perform the OR clause with the MultiSearcher and use a custom
made QueryFilter to filter the results that you don't need out of the first
index.

~Andrew

On Wed, Jul 29, 2009 at 3:22 PM, Andrei Alecu <[email protected]>wrote:

Right, I was doing two separate searches before, but I was hoping there was
a better way.

Thanks.


Digy wrote:

Either you have to reindex "Index A" and add a "visible" field with values
both 0 and 1, or make two seperate searches.

DIGY

-----Original Message-----
From: Andrei Alecu [mailto:[email protected]] Sent: Wednesday, July
29, 2009 9:54 PM
To: [email protected]
Subject: Is this query possible?

Hello all,

I have a MultiSearcher searching two separate indexes.

One of the indexes (index B) has some extra terms in its documents
compared to the other (index A).

Consider this scenario:

Index A documents:
field: fulltext

Index B documents:
field: fulltext
field: visible

I want for a query such as :

fulltext:"car" AND visible:1

To return all the matching "car" results in Index A, thus ignoring the
'visibile' constraint if it's not defined for the document. How can I do
that? Right now the results completely skip Index A because of no matching
'visible' field.

Thanks.










Reply via email to