If I understand you correctly, you want a query like
+body:hello +(+body:test -header:xy)
interpreted like
+body:hello +(body:test -body:xy)
.
For this, you can write a replacer method which traverses through the parsed tree and replaces the fields when reaching the objects containing the field name (e.g. Term, PhraseQuery, SpanNearQuery or whatever you have).
In Java you can change the field name of objects from those classes only via reflection. The other option would be to clone the parsed tree with other field names.
You can write a "replacer method" which takes a query object and handles it depending on the query type (i.e. for boolean query, phrase query, term query, ...).
- In case of a boolean query you can iterate trough the clauses and delegate the sub-queries recursively to the replacer method.
- In case of a term query you can replace the field in the term.
- In case of a phrase query you can replace the field in the query.
- and so on...
If you would choose the cloning way your methods would return a new object instead.
Edit:
Here is an example code for Java with 4 query types (boosts not considered):
public static Query forceField(Query q, String field) {
if(q instanceof BooleanQuery) {
BooleanQuery newQ = new BooleanQuery();
for (BooleanClause clause : (BooleanQuery)q) {
newQ.add(forceField(clause.getQuery(), field), clause.getOccur());
}
return newQ;
}else if(q instanceof TermQuery) {
return new TermQuery(new Term(field, ((TermQuery)q).getTerm().text()));
}else if(q instanceof PhraseQuery) {
PhraseQuery phraseQuery = new PhraseQuery();
Term[] terms = ((PhraseQuery)q).getTerms();
for (int i = 0; i < terms.length; i++) {
phraseQuery.add(new Term(field, terms[i].text()), ((PhraseQuery)q).getPositions()[i]);
}
return phraseQuery;
}else if(q instanceof WildcardQuery) {
return new WildcardQuery(new Term(field, ((WildcardQuery)q).getTerm().text()));
} else {
throw new UnsupportedOperationException("Query type not known: " + q.getClass());
}
}
Another option which is not so clean would be to use the toString of the whole query and replace all field in it and parse it again.