001: /*
002: * Copyright 2003-2004 Michael Franken, Zilverline.
003: *
004: * The contents of this file, or the files included with this file, are subject to
005: * the current version of ZILVERLINE Collaborative Source License for the
006: * Zilverline Search Engine (the "License"); You may not use this file except in
007: * compliance with the License.
008: *
009: * You may obtain a copy of the License at
010: *
011: * http://www.zilverline.org.
012: *
013: * See the License for the rights, obligations and
014: * limitations governing use of the contents of the file.
015: *
016: * The Original and Upgraded Code is the Zilverline Search Engine. The developer of
017: * the Original and Upgraded Code is Michael Franken. Michael Franken owns the
018: * copyrights in the portions it created. All Rights Reserved.
019: *
020: */
021:
022: package org.zilverline.lucene;
023:
024: import java.io.IOException;
025: import java.io.StringReader;
026: import java.util.Iterator;
027: import java.util.Map;
028: import java.util.Vector;
029:
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032:
033: import org.apache.lucene.analysis.Analyzer;
034: import org.apache.lucene.analysis.TokenStream;
035: import org.apache.lucene.index.Term;
036: import org.apache.lucene.queryParser.ParseException;
037: import org.apache.lucene.queryParser.QueryParser;
038: import org.apache.lucene.search.BooleanQuery;
039: import org.apache.lucene.search.PhraseQuery;
040: import org.apache.lucene.search.Query;
041:
042: /**
043: * BoostingParser extends QueryParser by boosting its terms.
044: */
045: public class BoostingParser extends QueryParser {
046: /** logger for Commons logging. */
047: private static Log log = LogFactory.getLog(BoostingParser.class);
048:
049: private String defaultField = "contents";
050:
051: private BoostFactor factors;
052:
053: /**
054: * @param factors The factors to set.
055: */
056: public void setFactors(BoostFactor factors) {
057: this .factors = factors;
058: }
059:
060: public BoostingParser(String f, Analyzer a) {
061: super (f, a);
062: defaultField = f;
063: }
064:
065: /**
066: * Callback that returns Query with boosted fields using BoostFactors
067: *
068: * @param field the field to query
069: * @param analyzer the analyzer to use
070: * @param queryText the query
071: *
072: * @return Query object
073: *
074: * @throws ParseException if Query can't be made
075: *
076: */
077: protected Query getFieldQuery(String field, Analyzer analyzer,
078: String queryText) throws ParseException {
079: // Use the analyzer to get all the tokens, and then build a TermQuery,
080: // PhraseQuery, or nothing based on the term count
081: // for field that contain 'contents' add boostfactors for other terms
082: // specified in BoostFactor
083: if (factors != null && factors.getFactors() != null
084: && !factors.getFactors().isEmpty()
085: && defaultField.equals(field)) {
086: TokenStream source = analyzer.tokenStream(field,
087: new StringReader(queryText));
088: Vector v = new Vector();
089: org.apache.lucene.analysis.Token t;
090:
091: while (true) {
092: try {
093: t = source.next();
094: } catch (IOException e) {
095: t = null;
096: }
097: if (t == null) {
098: break;
099: }
100: v.addElement(t.termText());
101: log.debug(field + " , " + t.termText());
102: }
103:
104: try {
105: source.close();
106: } catch (IOException e) {
107: log.error("Unexpected Exception");
108: }
109:
110: if (v.size() == 0) {
111: return null;
112: } else {
113: // create a new composed query
114: BooleanQuery bq = new BooleanQuery();
115:
116: // For all boostfactors create a new PhraseQuery
117: Iterator iter = factors.getFactors().entrySet()
118: .iterator();
119:
120: while (iter.hasNext()) {
121: Map.Entry element = (Map.Entry) iter.next();
122: String this Field = ((String) element.getKey())
123: .toLowerCase();
124: Float boost = (Float) element.getValue();
125: PhraseQuery q = new PhraseQuery();
126:
127: // and add all the terms of the query
128: for (int i = 0; i < v.size(); i++) {
129: q.add(new Term(this Field, (String) v
130: .elementAt(i)));
131: }
132:
133: // boost the query
134: q.setBoost(boost.floatValue());
135:
136: // and add it to the composed query
137: bq.add(q, false, false);
138: }
139: log.debug("Query: " + bq);
140:
141: return bq;
142: }
143: } else {
144: log.debug("Treat like normal query: " + queryText);
145: return super.getFieldQuery(field, analyzer, queryText);
146: }
147: }
148:
149: }
|