pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / queryparser / src / java / org / apache / lucene / queryParser / surround / query / SpanNearClauseFactory.java
1 package org.apache.lucene.queryParser.surround.query;
2 /**
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements.  See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 /*
20 SpanNearClauseFactory:
21
22 Operations:
23
24 - create for a field name and an indexreader.
25
26 - add a weighted Term
27   this should add a corresponding SpanTermQuery, or
28   increase the weight of an existing one.
29   
30 - add a weighted subquery SpanNearQuery 
31
32 - create a clause for SpanNearQuery from the things added above.
33   For this, create an array of SpanQuery's from the added ones.
34   The clause normally is a SpanOrQuery over the added subquery SpanNearQuery
35   the SpanTermQuery's for the added Term's
36 */
37
38 /* When  it is necessary to suppress double subqueries as much as possible:
39    hashCode() and equals() on unweighted SpanQuery are needed (possibly via getTerms(),
40    the terms are individually hashable).
41    Idem SpanNearQuery: hash on the subqueries and the slop.
42    Evt. merge SpanNearQuery's by adding the weights of the corresponding subqueries.
43  */
44  
45 /* To be determined:
46    Are SpanQuery weights handled correctly during search by Lucene?
47    Should the resulting SpanOrQuery be sorted?
48    Could other SpanQueries be added for use in this factory:
49    - SpanOrQuery: in principle yes, but it only has access to it's terms
50                   via getTerms(); are the corresponding weights available?
51    - SpanFirstQuery: treat similar to subquery SpanNearQuery. (ok?)
52    - SpanNotQuery: treat similar to subquery SpanNearQuery. (ok?)
53  */
54
55 import java.io.IOException;
56 import java.util.HashMap;
57 import java.util.Iterator;
58
59 import org.apache.lucene.index.IndexReader;
60 import org.apache.lucene.index.Term;
61 import org.apache.lucene.index.TermEnum;
62 import org.apache.lucene.search.Query;
63 import org.apache.lucene.search.spans.SpanNearQuery;
64 import org.apache.lucene.search.spans.SpanOrQuery;
65 import org.apache.lucene.search.spans.SpanQuery;
66 import org.apache.lucene.search.spans.SpanTermQuery;
67
68
69 public class SpanNearClauseFactory {
70   public SpanNearClauseFactory(IndexReader reader, String fieldName, BasicQueryFactory qf) {
71     this.reader = reader;
72     this.fieldName = fieldName;
73     this.weightBySpanQuery = new HashMap<SpanQuery, Float>(); 
74     this.qf = qf;
75   }
76   private IndexReader reader;
77   private String fieldName;
78   private HashMap<SpanQuery, Float> weightBySpanQuery;
79   private BasicQueryFactory qf;
80   
81   public IndexReader getIndexReader() {return reader;}
82   
83   public String getFieldName() {return fieldName;}
84
85   public BasicQueryFactory getBasicQueryFactory() {return qf;}
86   
87   public TermEnum getTermEnum(String termText) throws IOException {
88     return getIndexReader().terms(new Term(getFieldName(), termText));
89   }
90   
91   public int size() {return weightBySpanQuery.size();}
92   
93   public void clear() {weightBySpanQuery.clear();}
94
95   protected void addSpanQueryWeighted(SpanQuery sq, float weight) {
96     Float w = weightBySpanQuery.get(sq);
97     if (w != null)
98       w = Float.valueOf(w.floatValue() + weight);
99     else
100       w = Float.valueOf(weight);
101     weightBySpanQuery.put(sq, w); 
102   }
103   
104   public void addTermWeighted(Term t, float weight) throws IOException {   
105     SpanTermQuery stq = qf.newSpanTermQuery(t);
106     /* CHECKME: wrap in Hashable...? */
107     addSpanQueryWeighted(stq, weight);
108   }
109   
110   public void addSpanNearQuery(Query q) {
111     if (q == SrndQuery.theEmptyLcnQuery)
112       return;
113     if (! (q instanceof SpanNearQuery))
114       throw new AssertionError("Expected SpanNearQuery: " + q.toString(getFieldName()));
115     /* CHECKME: wrap in Hashable...? */
116     addSpanQueryWeighted((SpanNearQuery)q, q.getBoost());
117   }
118   
119   public SpanQuery makeSpanNearClause() {
120     SpanQuery [] spanQueries = new SpanQuery[size()];
121     Iterator<SpanQuery> sqi = weightBySpanQuery.keySet().iterator();
122     int i = 0;
123     while (sqi.hasNext()) {
124       SpanQuery sq = sqi.next();
125       sq.setBoost(weightBySpanQuery.get(sq).floatValue());
126       spanQueries[i++] = sq;
127     }
128     
129     if (spanQueries.length == 1)
130       return spanQueries[0];
131     else
132       return new SpanOrQuery(spanQueries);
133   }
134 }
135