pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / misc / src / test / org / apache / lucene / misc / TestLengthNormModifier.java
1 package org.apache.lucene.misc;
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
22 import org.apache.lucene.analysis.MockAnalyzer;
23 import org.apache.lucene.document.Document;
24 import org.apache.lucene.document.Field;
25 import org.apache.lucene.index.FieldInvertState;
26 import org.apache.lucene.index.FieldNormModifier;
27 import org.apache.lucene.index.IndexReader;
28 import org.apache.lucene.index.IndexWriter;
29 import org.apache.lucene.index.Term;
30 import org.apache.lucene.search.Collector;
31 import org.apache.lucene.search.DefaultSimilarity;
32 import org.apache.lucene.search.IndexSearcher;
33 import org.apache.lucene.search.Scorer;
34 import org.apache.lucene.search.Similarity;
35 import org.apache.lucene.search.TermQuery;
36 import org.apache.lucene.store.Directory;
37 import org.apache.lucene.util.LuceneTestCase;
38
39 /**
40  * Tests changing the norms after changing the simularity
41  */
42 public class TestLengthNormModifier extends LuceneTestCase {
43     public static int NUM_DOCS = 5;
44
45     public Directory store;
46
47     /** inverts the normal notion of lengthNorm */
48     public static Similarity s = new DefaultSimilarity() {
49         @Override
50         public float computeNorm(String fieldName, FieldInvertState state) {
51           return state.getBoost() * (discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength());
52         }
53       };
54     
55     @Override
56     public void setUp() throws Exception {
57       super.setUp();
58       store = newDirectory();
59         IndexWriter writer = new IndexWriter(store, newIndexWriterConfig(
60                                                                          TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
61         
62         for (int i = 0; i < NUM_DOCS; i++) {
63             Document d = new Document();
64             d.add(newField("field", "word",
65                             Field.Store.YES, Field.Index.ANALYZED));
66             d.add(newField("nonorm", "word",
67                             Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
68                 
69             for (int j = 1; j <= i; j++) {
70                 d.add(newField("field", "crap",
71                                 Field.Store.YES, Field.Index.ANALYZED));
72                 d.add(newField("nonorm", "more words",
73                                 Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
74             }
75             writer.addDocument(d);
76         }
77         writer.close();
78     }
79     
80     @Override
81     public void tearDown() throws Exception {
82       store.close();
83       super.tearDown();
84     }
85     
86     public void testMissingField() throws Exception {
87         FieldNormModifier fnm = new FieldNormModifier(store, s);
88         try {
89             fnm.reSetNorms("nobodyherebutuschickens");
90         } catch (IllegalStateException e) {
91             // expected
92         }
93     }
94         
95     public void testFieldWithNoNorm() throws Exception {
96
97         IndexReader r = IndexReader.open(store, false);
98         byte[] norms = r.norms("nonorm");
99
100         // sanity check, norms should all be 1
101         assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
102         assertNull(norms);
103
104         r.close();
105         
106         FieldNormModifier fnm = new FieldNormModifier(store, s);
107         try {
108             fnm.reSetNorms("nonorm");
109         } catch (IllegalStateException e) {
110           // expected
111         }
112
113         // nothing should have changed
114         r = IndexReader.open(store, false);
115         
116         norms = r.norms("nonorm");
117         assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
118   assertNull(norms);
119
120         r.close();
121         
122     }
123         
124     
125     public void testGoodCases() throws Exception {
126         
127         IndexSearcher searcher;
128         final float[] scores = new float[NUM_DOCS];
129         float lastScore = 0.0f;
130         
131         // default similarity should put docs with shorter length first
132         IndexReader reader = IndexReader.open(store, false);
133   searcher = new IndexSearcher(reader);
134   searcher.search(new TermQuery(new Term("field", "word")), new Collector() {
135     private int docBase = 0;
136     private Scorer scorer;
137     @Override
138     public final void collect(int doc) throws IOException {
139       scores[doc + docBase] = scorer.score();
140     }
141     @Override
142     public void setNextReader(IndexReader reader, int docBase) {
143       this.docBase = docBase;
144     }
145     @Override
146     public void setScorer(Scorer scorer) throws IOException {
147       this.scorer = scorer;
148     }
149     @Override
150     public boolean acceptsDocsOutOfOrder() {
151       return true;
152     }
153   });
154   searcher.close();
155   reader.close();
156         
157         lastScore = Float.MAX_VALUE;
158         for (int i = 0; i < NUM_DOCS; i++) {
159             String msg = "i=" + i + ", "+scores[i]+" <= "+lastScore;
160             assertTrue(msg, scores[i] <= lastScore);
161             //System.out.println(msg);
162             lastScore = scores[i];
163         }
164
165         // override the norms to be inverted
166         Similarity s = new DefaultSimilarity() {
167             @Override
168             public float computeNorm(String fieldName, FieldInvertState state) {
169               return state.getBoost() * (discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength());
170             }
171           };
172         FieldNormModifier fnm = new FieldNormModifier(store, s);
173         fnm.reSetNorms("field");
174
175         // new norm (with default similarity) should put longer docs first
176         reader = IndexReader.open(store, false);
177         searcher = new IndexSearcher(reader);
178         searcher.search(new TermQuery(new Term("field", "word")), new Collector() {
179       private int docBase = 0;
180       private Scorer scorer;
181       @Override
182       public final void collect(int doc) throws IOException {
183         scores[doc + docBase] = scorer.score();
184       }
185       @Override
186       public void setNextReader(IndexReader reader, int docBase) {
187         this.docBase = docBase;
188       }
189       @Override
190       public void setScorer(Scorer scorer) throws IOException {
191         this.scorer = scorer;
192       }
193       @Override
194       public boolean acceptsDocsOutOfOrder() {
195         return true;
196       }
197     });
198     searcher.close();
199     reader.close();
200         
201         lastScore = 0.0f;
202         for (int i = 0; i < NUM_DOCS; i++) {
203             String msg = "i=" + i + ", "+scores[i]+" >= "+lastScore;
204             assertTrue(msg, scores[i] >= lastScore);
205             //System.out.println(msg);
206             lastScore = scores[i];
207         }
208         
209     }
210 }