001: package org.apache.lucene.queryParser.surround.query;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: /*
021: SpanNearClauseFactory:
022:
023: Operations:
024:
025: - create for a field name and an indexreader.
026:
027: - add a weighted Term
028: this should add a corresponding SpanTermQuery, or
029: increase the weight of an existing one.
030:
031: - add a weighted subquery SpanNearQuery
032:
033: - create a clause for SpanNearQuery from the things added above.
034: For this, create an array of SpanQuery's from the added ones.
035: The clause normally is a SpanOrQuery over the added subquery SpanNearQuery
036: the SpanTermQuery's for the added Term's
037: */
038:
039: /* When it is necessary to suppress double subqueries as much as possible:
040: hashCode() and equals() on unweighted SpanQuery are needed (possibly via getTerms(),
041: the terms are individually hashable).
042: Idem SpanNearQuery: hash on the subqueries and the slop.
043: Evt. merge SpanNearQuery's by adding the weights of the corresponding subqueries.
044: */
045:
046: /* To be determined:
047: Are SpanQuery weights handled correctly during search by Lucene?
048: Should the resulting SpanOrQuery be sorted?
049: Could other SpanQueries be added for use in this factory:
050: - SpanOrQuery: in principle yes, but it only has access to it's terms
051: via getTerms(); are the corresponding weights available?
052: - SpanFirstQuery: treat similar to subquery SpanNearQuery. (ok?)
053: - SpanNotQuery: treat similar to subquery SpanNearQuery. (ok?)
054: */
055:
056: import java.util.HashMap;
057: import java.util.Iterator;
058:
059: import java.util.Comparator;
060: import java.util.Arrays;
061:
062: import java.io.IOException;
063:
064: import org.apache.lucene.index.IndexReader;
065: import org.apache.lucene.index.Term;
066: import org.apache.lucene.index.TermEnum;
067:
068: import org.apache.lucene.search.Query;
069:
070: import org.apache.lucene.search.spans.SpanQuery;
071: import org.apache.lucene.search.spans.SpanNearQuery;
072: import org.apache.lucene.search.spans.SpanOrQuery;
073: import org.apache.lucene.search.spans.SpanTermQuery;
074:
075: public class SpanNearClauseFactory {
076: public SpanNearClauseFactory(IndexReader reader, String fieldName,
077: BasicQueryFactory qf) {
078: this .reader = reader;
079: this .fieldName = fieldName;
080: this .weightBySpanQuery = new HashMap();
081: this .qf = qf;
082: }
083:
084: private IndexReader reader;
085: private String fieldName;
086: private HashMap weightBySpanQuery;
087: private BasicQueryFactory qf;
088:
089: public IndexReader getIndexReader() {
090: return reader;
091: }
092:
093: public String getFieldName() {
094: return fieldName;
095: }
096:
097: public BasicQueryFactory getBasicQueryFactory() {
098: return qf;
099: }
100:
101: public TermEnum getTermEnum(String termText) throws IOException {
102: return getIndexReader().terms(
103: new Term(getFieldName(), termText));
104: }
105:
106: public int size() {
107: return weightBySpanQuery.size();
108: }
109:
110: public void clear() {
111: weightBySpanQuery.clear();
112: }
113:
114: protected void addSpanQueryWeighted(SpanQuery sq, float weight) {
115: Float w = (Float) weightBySpanQuery.get(sq);
116: if (w != null)
117: w = new Float(w.floatValue() + weight);
118: else
119: w = new Float(weight);
120: weightBySpanQuery.put(sq, w);
121: }
122:
123: public void addTermWeighted(Term t, float weight)
124: throws IOException {
125: SpanTermQuery stq = qf.newSpanTermQuery(t);
126: /* CHECKME: wrap in Hashable...? */
127: addSpanQueryWeighted(stq, weight);
128: }
129:
130: public void addSpanNearQuery(Query q) {
131: if (q == SrndQuery.theEmptyLcnQuery)
132: return;
133: if (!(q instanceof SpanNearQuery))
134: throw new AssertionError("Expected SpanNearQuery: "
135: + q.toString(getFieldName()));
136: /* CHECKME: wrap in Hashable...? */
137: addSpanQueryWeighted((SpanNearQuery) q, q.getBoost());
138: }
139:
140: public SpanQuery makeSpanNearClause() {
141: SpanQuery[] spanQueries = new SpanQuery[size()];
142: Iterator sqi = weightBySpanQuery.keySet().iterator();
143: int i = 0;
144: while (sqi.hasNext()) {
145: SpanQuery sq = (SpanQuery) sqi.next();
146: sq.setBoost(((Float) weightBySpanQuery.get(sq))
147: .floatValue());
148: spanQueries[i++] = sq;
149: }
150:
151: if (spanQueries.length == 1)
152: return spanQueries[0];
153: else
154: return new SpanOrQuery(spanQueries);
155: }
156: }
|