On Thu, 27 Aug 2009 10:48:42 +0200, Emmanuel Bernard
<emmanuel(a)hibernate.org> wrote:
Did I make my case?
Yes. I can agree that your code is more readable and it will help building
queries.
That said, why not suggesting something like this to the Lucene folks
directly. I agree on
this one with Manik.
--Hardy
String search = "harry potter";
SealedQueryBuilder qb = searchFactory.withEntityAnalyzer(Book.class);
Query luceneQuery =
qb.searchInMultipleFields()
.onField("title").boostedTo(4)
.onField("title_ngram")
.onField("description")
.onField("description_ngram").boostedTo(.25)
.forWords(search);
vs
String search = "harry potter";
Analyzer analyzer = searchFactory.getAnalyzer(Book.class);
Map<String,Float> boostPerField = new HashMap<String,Float>(2); //
boost factors
boostPerField.put( "title", (float) 4);
boostPerField.put( "title_ngram", (float) 1);
boostPerField.put( "description", (float) 1);
boostPerField.put( "description_ngram", (float) .25);
BooleanQuery luceneQuery = new BooleanQuery();
for ( Map.Entry<String, Float> entry : boostPerField.entrySet() ) {
final String fieldName = entry.getKey();
final Float boost = entry.getValue();
List<String> terms = new ArrayList<String>();
try {
Reader reader = new StringReader(search);
TokenStream stream = analyzer.tokenStream( fieldName, reader);
Token token = new Token();
token = stream.next(token);
while (token != null) {
if (token.termLength() != 0) {
String term = new String(token.termBuffer(), 0, token.termLength());
terms.add( term );
}
token = stream.next(token);
}
}
catch ( IOException e ) {
throw new RuntimeException("IO exception while reading String
stream??", e);
}
for (String term : terms) {
TermQuery termQuery = new TermQuery( new Term( fieldName, term ) );
termQuery.setBoost( boost );
luceneQuery.add( termQuery, BooleanClause.Occur.SHOULD );
}
}