- LUCENE-544 - allow per-field boosts to be specified.

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@465081 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Otis Gospodnetic 2006-10-17 22:26:57 +00:00
parent 3c35b82cb0
commit b75358ebc9
3 changed files with 73 additions and 0 deletions

View File

@ -36,6 +36,8 @@ New features
4. LUCENE-678: Added NativeFSLockFactory, which implements locking
using OS native locking (via java.nio.*). (Michael McCandless via Yonik Seeley)
5. LUCENE-544: Added the ability to specify different boosts for different
fields when using MultiFieldQueryParser (Matt Ericson via Otis Gospodnetic)
API Changes

View File

@ -24,6 +24,7 @@ import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.Query;
import java.util.Vector;
import java.util.Map;
/**
* A QueryParser which constructs queries to search multiple fields.
@ -35,6 +36,39 @@ public class MultiFieldQueryParser extends QueryParser
{
private String[] fields;
private Map boosts;
/**
* Creates a MultiFieldQueryParser.
* Allows passing of a map with term to Boost, and the boost to apply to each term.
*
* <p>It will, when parse(String query)
* is called, construct a query like this (assuming the query consists of
* two terms and you specify the two fields <code>title</code> and <code>body</code>):</p>
*
* <code>
* (title:term1 body:term1) (title:term2 body:term2)
* </code>
*
* <p>When setDefaultOperator(AND_OPERATOR) is set, the result will be:</p>
*
* <code>
* +(title:term1 body:term1) +(title:term2 body:term2)
* </code>
*
* <p>When you pass a boost (title=>5 body=>10) you can get </p>
*
* <code>
* +(title:term1^5.0 body:term1^10.0) +(title:term2^5.0 body:term2^10.0)
* </code>
*
* <p>In other words, all the query's terms must appear, but it doesn't matter in
* what fields they appear.</p>
*/
public MultiFieldQueryParser(String[] fields, Analyzer analyzer, Map boosts) {
this(fields,analyzer);
this.boosts = boosts;
}
/**
* Creates a MultiFieldQueryParser.
@ -67,6 +101,14 @@ public class MultiFieldQueryParser extends QueryParser
for (int i = 0; i < fields.length; i++) {
Query q = super.getFieldQuery(fields[i], queryText);
if (q != null) {
//If the user passes a map of boosts
if (boosts != null) {
//Get the boost from the map and apply them
Float boost = (Float)boosts.get(fields[i]);
if (boost != null) {
q.setBoost(boost.floatValue());
}
}
if (q instanceof PhraseQuery) {
((PhraseQuery) q).setSlop(slop);
}

View File

@ -32,6 +32,8 @@ import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
/**
* Tests QueryParser.
@ -95,6 +97,33 @@ public class TestMultiFieldQueryParser extends TestCase {
}
public void testBoostsSimple() throws Exception {
Map boosts = new HashMap();
boosts.put("b", new Float(5));
boosts.put("t", new Float(10));
String[] fields = {"b", "t"};
MultiFieldQueryParser mfqp = new MultiFieldQueryParser(fields, new StandardAnalyzer(), boosts);
//Check for simple
Query q = mfqp.parse("one");
assertEquals("b:one^5.0 t:one^10.0", q.toString());
//Check for AND
q = mfqp.parse("one AND two");
assertEquals("+(b:one^5.0 t:one^10.0) +(b:two^5.0 t:two^10.0)", q.toString());
//Check for OR
q = mfqp.parse("one OR two");
assertEquals("(b:one^5.0 t:one^10.0) (b:two^5.0 t:two^10.0)", q.toString());
//Check for AND and a field
q = mfqp.parse("one AND two AND foo:test");
assertEquals("+(b:one^5.0 t:one^10.0) +(b:two^5.0 t:two^10.0) +foo:test", q.toString());
q = mfqp.parse("one^3 AND two^4");
assertEquals("+((b:one^5.0 t:one^10.0)^3.0) +((b:two^5.0 t:two^10.0)^4.0)", q.toString());
}
public void testStaticMethod1() throws ParseException {
String[] fields = {"b", "t"};