pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / misc / src / test / org / apache / lucene / index / TestFieldNormModifier.java
1 package org.apache.lucene.index;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21 import java.util.Arrays;
22
23 import org.apache.lucene.analysis.MockAnalyzer;
24 import org.apache.lucene.document.Document;
25 import org.apache.lucene.document.Field;
26 import org.apache.lucene.search.Collector;
27 import org.apache.lucene.search.DefaultSimilarity;
28 import org.apache.lucene.search.IndexSearcher;
29 import org.apache.lucene.search.Scorer;
30 import org.apache.lucene.search.Similarity;
31 import org.apache.lucene.search.TermQuery;
32 import org.apache.lucene.store.Directory;
33 import org.apache.lucene.util.LuceneTestCase;
34
35 /**
36  * Tests changing of field norms with a custom similarity and with fake norms.
37  */
38 public class TestFieldNormModifier extends LuceneTestCase {
39   public static int NUM_DOCS = 5;
40   
41   public Directory store;
42   
43   /** inverts the normal notion of lengthNorm */
44   public static Similarity s = new DefaultSimilarity() {
45     @Override
46     public float computeNorm(String fieldName, FieldInvertState state) {
47       return state.getBoost() * (discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength());
48     }
49   };
50   
51   @Override
52   public void setUp() throws Exception {
53     super.setUp();
54     store = newDirectory();
55     IndexWriter writer = new IndexWriter(store, newIndexWriterConfig(
56                                                                      TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
57     
58     for (int i = 0; i < NUM_DOCS; i++) {
59       Document d = new Document();
60       d.add(newField("field", "word", Field.Store.YES, Field.Index.ANALYZED));
61       d.add(newField("nonorm", "word", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
62       d.add(newField("untokfield", "20061212 20071212", Field.Store.YES, Field.Index.ANALYZED));
63       
64       for (int j = 1; j <= i; j++) {
65         d.add(newField("field", "crap", Field.Store.YES, Field.Index.ANALYZED));
66         d.add(newField("nonorm", "more words", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
67       }
68       writer.addDocument(d);
69     }
70     writer.close();
71   }
72   
73   @Override
74   public void tearDown() throws Exception {
75     store.close();
76     super.tearDown();
77   }
78   
79   public void testMissingField() throws Exception {
80     FieldNormModifier fnm = new FieldNormModifier(store, s);
81     try {
82       fnm.reSetNorms("nobodyherebutuschickens");
83     } catch (IllegalStateException e) {
84       // expected
85     }
86   }
87   
88   public void testFieldWithNoNorm() throws Exception {
89     
90     IndexReader r = IndexReader.open(store, false);
91     byte[] norms = r.norms("nonorm");
92     
93     // sanity check, norms should all be 1
94     assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
95     assertNull(norms);
96     
97     r.close();
98     
99     FieldNormModifier fnm = new FieldNormModifier(store, s);
100     try {
101       fnm.reSetNorms("nonorm");
102     } catch (IllegalStateException e) {
103       // expected
104     }
105     
106     // nothing should have changed
107     r = IndexReader.open(store, false);
108     
109     norms = r.norms("nonorm");
110     assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
111     assertNull(norms);
112
113     r.close();
114   }
115   
116   
117   public void testGoodCases() throws Exception {
118     
119     IndexReader reader = IndexReader.open(store);
120     IndexSearcher searcher = new IndexSearcher(reader);
121     final float[] scores = new float[NUM_DOCS];
122     float lastScore = 0.0f;
123     
124     // default similarity should put docs with shorter length first
125     searcher.search(new TermQuery(new Term("field", "word")), new Collector() {
126       private int docBase = 0;
127       private Scorer scorer;
128       
129       @Override
130       public final void collect(int doc) throws IOException {
131         scores[doc + docBase] = scorer.score();
132       }
133       @Override
134       public void setNextReader(IndexReader reader, int docBase) {
135         this.docBase = docBase;
136       }
137       @Override
138       public void setScorer(Scorer scorer) throws IOException {
139         this.scorer = scorer;
140       }
141       @Override
142       public boolean acceptsDocsOutOfOrder() {
143         return true;
144       }
145     });
146     searcher.close();
147     reader.close();
148     
149     lastScore = Float.MAX_VALUE;
150     for (int i = 0; i < NUM_DOCS; i++) {
151       String msg = "i=" + i + ", " + scores[i] + " <= " + lastScore;
152       assertTrue(msg, scores[i] <= lastScore);
153       //System.out.println(msg);
154       lastScore = scores[i];
155     }
156
157     FieldNormModifier fnm = new FieldNormModifier(store, s);
158     fnm.reSetNorms("field");
159     
160     // new norm (with default similarity) should put longer docs first
161     reader = IndexReader.open(store);
162     searcher = new IndexSearcher(reader);
163     searcher.search(new TermQuery(new Term("field", "word")),  new Collector() {
164       private int docBase = 0;
165       private Scorer scorer;
166       @Override
167       public final void collect(int doc) throws IOException {
168         scores[doc + docBase] = scorer.score();
169       }
170       @Override
171       public void setNextReader(IndexReader reader, int docBase) {
172         this.docBase = docBase;
173       }
174       @Override
175       public void setScorer(Scorer scorer) throws IOException {
176         this.scorer = scorer;
177       }
178       @Override
179       public boolean acceptsDocsOutOfOrder() {
180         return true;
181       }
182     });
183     searcher.close();
184     reader.close();
185     
186     lastScore = 0.0f;
187     for (int i = 0; i < NUM_DOCS; i++) {
188       String msg = "i=" + i + ", " + scores[i] + " >= " + lastScore;
189       assertTrue(msg, scores[i] >= lastScore);
190       //System.out.println(msg);
191       lastScore = scores[i];
192     }
193   }
194
195   public void testNormKiller() throws IOException {
196
197     IndexReader r = IndexReader.open(store, false);
198     byte[] oldNorms = r.norms("untokfield");    
199     r.close();
200     
201     FieldNormModifier fnm = new FieldNormModifier(store, s);
202     fnm.reSetNorms("untokfield");
203
204     r = IndexReader.open(store, false);
205     byte[] newNorms = r.norms("untokfield");
206     r.close();
207     assertFalse(Arrays.equals(oldNorms, newNorms));    
208
209     
210     // verify that we still get documents in the same order as originally
211     IndexReader reader = IndexReader.open(store);
212     IndexSearcher searcher = new IndexSearcher(reader);
213     final float[] scores = new float[NUM_DOCS];
214     float lastScore = 0.0f;
215     
216     // default similarity should return the same score for all documents for this query
217     searcher.search(new TermQuery(new Term("untokfield", "20061212")), new Collector() {
218       private int docBase = 0;
219       private Scorer scorer;
220       @Override
221       public final void collect(int doc) throws IOException {
222         scores[doc + docBase] = scorer.score();
223       }
224       @Override
225       public void setNextReader(IndexReader reader, int docBase) {
226         this.docBase = docBase;
227       }
228       @Override
229       public void setScorer(Scorer scorer) throws IOException {
230         this.scorer = scorer;
231       }
232       @Override
233       public boolean acceptsDocsOutOfOrder() {
234         return true;
235       }
236     });
237     searcher.close();
238     reader.close();
239     
240     lastScore = scores[0];
241     for (int i = 0; i < NUM_DOCS; i++) {
242       String msg = "i=" + i + ", " + scores[i] + " == " + lastScore;
243       assertTrue(msg, scores[i] == lastScore);
244       //System.out.println(msg);
245       lastScore = scores[i];
246     }
247   }
248 }