001: package org.apache.lucene.search.spans;
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: import org.apache.lucene.index.IndexReader;
021: import org.apache.lucene.index.Term;
022: import org.apache.lucene.search.*;
023:
024: import java.io.IOException;
025: import java.util.HashSet;
026: import java.util.Iterator;
027: import java.util.Set;
028:
029: /**
030: * Expert-only. Public for use by other weight implementations
031: */
032: public class SpanWeight implements Weight {
033: protected Similarity similarity;
034: protected float value;
035: protected float idf;
036: protected float queryNorm;
037: protected float queryWeight;
038:
039: protected Set terms;
040: protected SpanQuery query;
041:
042: public SpanWeight(SpanQuery query, Searcher searcher)
043: throws IOException {
044: this .similarity = query.getSimilarity(searcher);
045: this .query = query;
046: terms = new HashSet();
047: query.extractTerms(terms);
048:
049: idf = this .query.getSimilarity(searcher).idf(terms, searcher);
050: }
051:
052: public Query getQuery() {
053: return query;
054: }
055:
056: public float getValue() {
057: return value;
058: }
059:
060: public float sumOfSquaredWeights() throws IOException {
061: queryWeight = idf * query.getBoost(); // compute query weight
062: return queryWeight * queryWeight; // square it
063: }
064:
065: public void normalize(float queryNorm) {
066: this .queryNorm = queryNorm;
067: queryWeight *= queryNorm; // normalize query weight
068: value = queryWeight * idf; // idf for document
069: }
070:
071: public Scorer scorer(IndexReader reader) throws IOException {
072: return new SpanScorer(query.getSpans(reader), this , similarity,
073: reader.norms(query.getField()));
074: }
075:
076: public Explanation explain(IndexReader reader, int doc)
077: throws IOException {
078:
079: ComplexExplanation result = new ComplexExplanation();
080: result.setDescription("weight(" + getQuery() + " in " + doc
081: + "), product of:");
082: String field = ((SpanQuery) getQuery()).getField();
083:
084: StringBuffer docFreqs = new StringBuffer();
085: Iterator i = terms.iterator();
086: while (i.hasNext()) {
087: Term term = (Term) i.next();
088: docFreqs.append(term.text());
089: docFreqs.append("=");
090: docFreqs.append(reader.docFreq(term));
091:
092: if (i.hasNext()) {
093: docFreqs.append(" ");
094: }
095: }
096:
097: Explanation idfExpl = new Explanation(idf, "idf(" + field
098: + ": " + docFreqs + ")");
099:
100: // explain query weight
101: Explanation queryExpl = new Explanation();
102: queryExpl.setDescription("queryWeight(" + getQuery()
103: + "), product of:");
104:
105: Explanation boostExpl = new Explanation(getQuery().getBoost(),
106: "boost");
107: if (getQuery().getBoost() != 1.0f)
108: queryExpl.addDetail(boostExpl);
109: queryExpl.addDetail(idfExpl);
110:
111: Explanation queryNormExpl = new Explanation(queryNorm,
112: "queryNorm");
113: queryExpl.addDetail(queryNormExpl);
114:
115: queryExpl.setValue(boostExpl.getValue() * idfExpl.getValue()
116: * queryNormExpl.getValue());
117:
118: result.addDetail(queryExpl);
119:
120: // explain field weight
121: ComplexExplanation fieldExpl = new ComplexExplanation();
122: fieldExpl.setDescription("fieldWeight(" + field + ":"
123: + query.toString(field) + " in " + doc
124: + "), product of:");
125:
126: Explanation tfExpl = scorer(reader).explain(doc);
127: fieldExpl.addDetail(tfExpl);
128: fieldExpl.addDetail(idfExpl);
129:
130: Explanation fieldNormExpl = new Explanation();
131: byte[] fieldNorms = reader.norms(field);
132: float fieldNorm = fieldNorms != null ? Similarity
133: .decodeNorm(fieldNorms[doc]) : 0.0f;
134: fieldNormExpl.setValue(fieldNorm);
135: fieldNormExpl.setDescription("fieldNorm(field=" + field
136: + ", doc=" + doc + ")");
137: fieldExpl.addDetail(fieldNormExpl);
138:
139: fieldExpl.setMatch(Boolean.valueOf(tfExpl.isMatch()));
140: fieldExpl.setValue(tfExpl.getValue() * idfExpl.getValue()
141: * fieldNormExpl.getValue());
142:
143: result.addDetail(fieldExpl);
144: result.setMatch(fieldExpl.getMatch());
145:
146: // combine them
147: result.setValue(queryExpl.getValue() * fieldExpl.getValue());
148:
149: if (queryExpl.getValue() == 1.0f)
150: return fieldExpl;
151:
152: return result;
153: }
154: }
|