1 package org.apache.lucene.index;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 import java.io.IOException;
21 import java.util.Arrays;
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;
36 * Tests changing of field norms with a custom similarity and with fake norms.
38 public class TestFieldNormModifier extends LuceneTestCase {
39 public static int NUM_DOCS = 5;
41 public Directory store;
43 /** inverts the normal notion of lengthNorm */
44 public static Similarity s = new DefaultSimilarity() {
46 public float computeNorm(String fieldName, FieldInvertState state) {
47 return state.getBoost() * (discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength());
52 public void setUp() throws Exception {
54 store = newDirectory();
55 IndexWriter writer = new IndexWriter(store, newIndexWriterConfig(
56 TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
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));
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));
68 writer.addDocument(d);
74 public void tearDown() throws Exception {
79 public void testMissingField() throws Exception {
80 FieldNormModifier fnm = new FieldNormModifier(store, s);
82 fnm.reSetNorms("nobodyherebutuschickens");
83 } catch (IllegalStateException e) {
88 public void testFieldWithNoNorm() throws Exception {
90 IndexReader r = IndexReader.open(store, false);
91 byte[] norms = r.norms("nonorm");
93 // sanity check, norms should all be 1
94 assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
99 FieldNormModifier fnm = new FieldNormModifier(store, s);
101 fnm.reSetNorms("nonorm");
102 } catch (IllegalStateException e) {
106 // nothing should have changed
107 r = IndexReader.open(store, false);
109 norms = r.norms("nonorm");
110 assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
117 public void testGoodCases() throws Exception {
119 IndexSearcher searcher = new IndexSearcher(store, true);
120 final float[] scores = new float[NUM_DOCS];
121 float lastScore = 0.0f;
123 // default similarity should put docs with shorter length first
124 searcher.search(new TermQuery(new Term("field", "word")), new Collector() {
125 private int docBase = 0;
126 private Scorer scorer;
129 public final void collect(int doc) throws IOException {
130 scores[doc + docBase] = scorer.score();
133 public void setNextReader(IndexReader reader, int docBase) {
134 this.docBase = docBase;
137 public void setScorer(Scorer scorer) throws IOException {
138 this.scorer = scorer;
141 public boolean acceptsDocsOutOfOrder() {
147 lastScore = Float.MAX_VALUE;
148 for (int i = 0; i < NUM_DOCS; i++) {
149 String msg = "i=" + i + ", " + scores[i] + " <= " + lastScore;
150 assertTrue(msg, scores[i] <= lastScore);
151 //System.out.println(msg);
152 lastScore = scores[i];
155 FieldNormModifier fnm = new FieldNormModifier(store, s);
156 fnm.reSetNorms("field");
158 // new norm (with default similarity) should put longer docs first
159 searcher = new IndexSearcher(store, true);
160 searcher.search(new TermQuery(new Term("field", "word")), new Collector() {
161 private int docBase = 0;
162 private Scorer scorer;
164 public final void collect(int doc) throws IOException {
165 scores[doc + docBase] = scorer.score();
168 public void setNextReader(IndexReader reader, int docBase) {
169 this.docBase = docBase;
172 public void setScorer(Scorer scorer) throws IOException {
173 this.scorer = scorer;
176 public boolean acceptsDocsOutOfOrder() {
183 for (int i = 0; i < NUM_DOCS; i++) {
184 String msg = "i=" + i + ", " + scores[i] + " >= " + lastScore;
185 assertTrue(msg, scores[i] >= lastScore);
186 //System.out.println(msg);
187 lastScore = scores[i];
191 public void testNormKiller() throws IOException {
193 IndexReader r = IndexReader.open(store, false);
194 byte[] oldNorms = r.norms("untokfield");
197 FieldNormModifier fnm = new FieldNormModifier(store, s);
198 fnm.reSetNorms("untokfield");
200 r = IndexReader.open(store, false);
201 byte[] newNorms = r.norms("untokfield");
203 assertFalse(Arrays.equals(oldNorms, newNorms));
206 // verify that we still get documents in the same order as originally
207 IndexSearcher searcher = new IndexSearcher(store, true);
208 final float[] scores = new float[NUM_DOCS];
209 float lastScore = 0.0f;
211 // default similarity should return the same score for all documents for this query
212 searcher.search(new TermQuery(new Term("untokfield", "20061212")), new Collector() {
213 private int docBase = 0;
214 private Scorer scorer;
216 public final void collect(int doc) throws IOException {
217 scores[doc + docBase] = scorer.score();
220 public void setNextReader(IndexReader reader, int docBase) {
221 this.docBase = docBase;
224 public void setScorer(Scorer scorer) throws IOException {
225 this.scorer = scorer;
228 public boolean acceptsDocsOutOfOrder() {
234 lastScore = scores[0];
235 for (int i = 0; i < NUM_DOCS; i++) {
236 String msg = "i=" + i + ", " + scores[i] + " == " + lastScore;
237 assertTrue(msg, scores[i] == lastScore);
238 //System.out.println(msg);
239 lastScore = scores[i];