package org.apache.lucene.queries; /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.RandomIndexWriter; import org.apache.lucene.index.SlowCompositeReaderWrapper; import org.apache.lucene.index.Term; import org.apache.lucene.search.DocIdSet; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Filter; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.MatchAllDocsQuery; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.util.LuceneTestCase; import org.apache.lucene.util.TestUtil; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; public class TermFilterTest extends LuceneTestCase { public void testCachability() throws Exception { TermFilter a = termFilter("field1", "a"); HashSet<Filter> cachedFilters = new HashSet<>(); cachedFilters.add(a); assertTrue("Must be cached", cachedFilters.contains(termFilter("field1", "a"))); assertFalse("Must not be cached", cachedFilters.contains(termFilter("field1", "b"))); assertFalse("Must not be cached", cachedFilters.contains(termFilter("field2", "a"))); } public void testMissingTermAndField() throws Exception { String fieldName = "field1"; Directory rd = newDirectory(); RandomIndexWriter w = new RandomIndexWriter(random(), rd); Document doc = new Document(); doc.add(newStringField(fieldName, "value1", Field.Store.NO)); w.addDocument(doc); IndexReader reader = SlowCompositeReaderWrapper.wrap(w.getReader()); assertTrue(reader.getContext() instanceof AtomicReaderContext); AtomicReaderContext context = (AtomicReaderContext) reader.getContext(); w.close(); DocIdSet idSet = termFilter(fieldName, "value1").getDocIdSet(context, context.reader().getLiveDocs()); assertNotNull("must not be null", idSet); DocIdSetIterator iter = idSet.iterator(); assertEquals(iter.nextDoc(), 0); assertEquals(iter.nextDoc(), DocIdSetIterator.NO_MORE_DOCS); idSet = termFilter(fieldName, "value2").getDocIdSet(context, context.reader().getLiveDocs()); assertNull("must be null", idSet); idSet = termFilter("field2", "value1").getDocIdSet(context, context.reader().getLiveDocs()); assertNull("must be null", idSet); reader.close(); rd.close(); } public void testRandom() throws IOException { Directory dir = newDirectory(); RandomIndexWriter w = new RandomIndexWriter(random(), dir); int num = atLeast(100); List<Term> terms = new ArrayList<>(); for (int i = 0; i < num; i++) { String field = "field" + i; String string = TestUtil.randomRealisticUnicodeString(random()); terms.add(new Term(field, string)); Document doc = new Document(); doc.add(newStringField(field, string, Field.Store.NO)); w.addDocument(doc); } IndexReader reader = w.getReader(); w.close(); IndexSearcher searcher = newSearcher(reader); int numQueries = atLeast(10); for (int i = 0; i < numQueries; i++) { Term term = terms.get(random().nextInt(num)); TopDocs queryResult = searcher.search(new TermQuery(term), reader.maxDoc()); MatchAllDocsQuery matchAll = new MatchAllDocsQuery(); final TermFilter filter = termFilter(term); TopDocs filterResult = searcher.search(matchAll, filter, reader.maxDoc()); assertEquals(filterResult.totalHits, queryResult.totalHits); ScoreDoc[] scoreDocs = filterResult.scoreDocs; for (int j = 0; j < scoreDocs.length; j++) { assertEquals(scoreDocs[j].doc, queryResult.scoreDocs[j].doc); } } reader.close(); dir.close(); } public void testHashCodeAndEquals() { int num = atLeast(100); for (int i = 0; i < num; i++) { String field1 = "field" + i; String field2 = "field" + i + num; String value1 = TestUtil.randomRealisticUnicodeString(random()); String value2 = value1 + "x"; // this must be not equal to value1 TermFilter filter1 = termFilter(field1, value1); TermFilter filter2 = termFilter(field1, value2); TermFilter filter3 = termFilter(field2, value1); TermFilter filter4 = termFilter(field2, value2); TermFilter[] filters = new TermFilter[]{filter1, filter2, filter3, filter4}; for (int j = 0; j < filters.length; j++) { TermFilter termFilter = filters[j]; for (int k = 0; k < filters.length; k++) { TermFilter otherTermFilter = filters[k]; if (j == k) { assertEquals(termFilter, otherTermFilter); assertEquals(termFilter.hashCode(), otherTermFilter.hashCode()); assertTrue(termFilter.equals(otherTermFilter)); } else { assertFalse(termFilter.equals(otherTermFilter)); } } } TermFilter filter5 = termFilter(field2, value2); assertEquals(filter5, filter4); assertEquals(filter5.hashCode(), filter4.hashCode()); assertTrue(filter5.equals(filter4)); assertEquals(filter5, filter4); assertTrue(filter5.equals(filter4)); } } public void testNoTerms() { try { new TermFilter(null); fail("must fail - no term!"); } catch (IllegalArgumentException e) {} try { new TermFilter(new Term(null)); fail("must fail - no field!"); } catch (IllegalArgumentException e) {} } public void testToString() { TermFilter termsFilter = new TermFilter(new Term("field1", "a")); assertEquals("field1:a", termsFilter.toString()); } private TermFilter termFilter(String field, String value) { return termFilter(new Term(field, value)); } private TermFilter termFilter(Term term) { return new TermFilter(term); } }