4
votes

I'm working on a Java webapp (Spring 3.x) that uses SOLR for its search engine. I want to be able to intercept the Lucene query and substitute a "virtual" search field for either one of two indexed fields, based upon a lookup service (if successful use a range search otherwise search a regular field).

E.g., given a query like field0:foo (field1:bar OR field1:bash) AND field2:bing (field1 being a virtual field)

manipulate the query to get field0:foo (field3:[42 TO 45] OR field4:bash) AND field2:bing

So after toying with the idea of just using a reg ex, I decided to look at the Lucene classes, to see if I could re-use existing code. I'd like to be able to get a parsed version of the query so as to iterate over the clauses, looking for certain fields to manipulate. Then re-generate the query string and pass it on to SOLR.

I've got close using Lucene's QueryParser but I can only get the terms and not the boolean operators:

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
QueryParser queryParser = new QueryParser(Version.LUCENE_30, "text", analyzer);
try {
    Query query = queryParser.parse(queryString);
    Set<Term> terms = new TreeSet<Term>();
    query.extractTerms(terms);

    for (Term t : terms) {
        logger.info("Term - field:" + t.field() + " | text:" + t.text());
    }
} catch (ParseException ex) {
    logger.warn(ex.getMessage(), ex);
}

I've looked at the BooleanQuery but haven't had luck there either. Please help.

1

1 Answers

4
votes

Make your own query parser:

class MyParser : MultiFieldQueryParser {
  @override
  public Query getFieldQuery(string field, string queryText) {
     if lookupSuccessful(field, queryText) { 
       return myQuery(field, queryText);
     }
     return base.getFieldQuery(field, queryText);
  }
}