package org.apache.lucene.search; /** * Copyright 2004 The Apache Software Foundation * * Licensed 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 junit.framework.TestCase; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.Term; import org.apache.lucene.queryParser.QueryParser; import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.analysis.SimpleAnalyzer; import org.apache.lucene.analysis.WhitespaceAnalyzer; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import java.io.IOException; /** Regression test to cover issue Lucene-72 * * @author Dejan Nenov * @version */ public class TestRegressionLucene72 extends TestCase { private RAMDirectory dir; private int docCount; private Analyzer theAnalyzer = new WhitespaceAnalyzer(); private IndexSearcher searcher; private Query theQuery; private Hits hits; private String resultDocs = ""; private String contentFieldName = "c"; private String idFieldName = "id"; public void setUp() throws Exception { dir = new RAMDirectory(); //setup hte data in the index initializeIndex(new String[] {"fruits vegetables tomatoes bananas"}); addDoc("fruits vegetables tomatoes kiwis"); addDoc("fruits vegetables peppers kiwis"); addDoc("fruits vegetables peppers bananas"); searcher = new IndexSearcher(dir); } public void tearDown() throws Exception { searcher.close(); dir.close(); } // initializeIndex, addDoc and insertDoc borrowed directly from //TestRanegQuery @author goller private void initializeIndex(String[] values) throws IOException { IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true); for (int i = 0; i < values.length; i++) { insertDoc(writer, values[i]); } writer.close(); } private void addDoc(String content) throws IOException { IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), false); insertDoc(writer, content); writer.close(); } private void insertDoc(IndexWriter writer, String content) throws IOException { Document doc = new Document(); doc.add(new Field(idFieldName, idFieldName + docCount, Field.Store.YES, Field.Index.UN_TOKENIZED)); doc.add(new Field(contentFieldName, content, Field.Store.YES, Field.Index.TOKENIZED)); writer.addDocument(doc); docCount++; } // getParser, getQuery and assertQueryEquals borrowed from org.apache.lucene.queryParser.TestQueryParser public QueryParser getParser(Analyzer a) throws Exception { if (a == null) a = new SimpleAnalyzer(); QueryParser qp = new QueryParser("field", a); qp.setDefaultOperator(QueryParser.OR_OPERATOR); return qp; } public Query getQuery(String query, Analyzer a) throws Exception { return getParser(a).parse(query); } public void assertQueryEquals(String query, Analyzer a, String result) throws Exception { Query q = getQuery(query, a); String s = q.toString("field"); if (!s.equals(result)) { fail("Query /" + query + "/ yielded /" + s + "/, expecting /" + result + "/"); } } // query string directly form the Lucene-72 issue: // the four documents in this test contain: //Doc1: "fruits vegetables tomatoes bananas" //Doc2: "fruits vegetables tomatoes kiwis" //Doc3: "fruits vegetables peppers kiwis" //Doc4: "fruits vegetables peppers bananas" public void testPrintCorpusAndQueries() { System.out.println("Iindex data and queries:\n" + "Doc1 = fruits vegetables tomatoes bananas\n" + "Doc2 = fruits vegetables tomatoes kiwis\n" + "Doc3 = fruits vegetables peppers kiwis\n" + "Doc4 = fruits vegetables peppers bananas\n" + "theSimpleQueryS = +c:fruits +c:vegetables -c:tomatoes -c:bananas\n" + "theANDQueryS = +(c:fruits c:vegetables) AND (-c:tomatoes -c:bananas)\n" + "theNOTQueryS = +(c:fruits c:vegetables) NOT (c:tomatoes c:bananas)" ); } public void testSIMPLE() throws Exception { //theSIMPLEquery should return only Doc3 String theSimpleQueryS = "+c:fruits +c:vegetables -c:tomatoes -c:bananas"; assertQueryEquals(theSimpleQueryS, theAnalyzer, "+c:fruits +c:vegetables -c:tomatoes -c:bananas"); theQuery = getQuery(theSimpleQueryS,theAnalyzer); hits = searcher.search(theQuery); resultDocs = ""; System.out.println("SimpleQuery: hits.length=" + hits.length()); for (int i = 0; i < hits.length(); i++) { System.out.println("SimpleQuery:Doc[" + i + "]= "+ hits.doc(i).get(contentFieldName)); resultDocs += hits.doc(i).get(contentFieldName); } assertEquals("resultDocs =" + resultDocs, 1, hits.length()); } public void testAND() throws Exception { //theANDquery should return Doc2, Doc3, Doc4 - because the clause left of the AND returns all docs // and the clause to the right of the AND returns all docs EXCEPT DOC1 // Note that we have used QueryParser.OR_OPERATOR above //First test if the Query Parser does what we expect String theANDQueryS = "+(c:fruits c:vegetables) AND (-c:tomatoes -c:bananas)"; assertQueryEquals(theANDQueryS, theAnalyzer, "+(c:fruits c:vegetables) +(-c:tomatoes -c:bananas)"); theQuery = getQuery(theANDQueryS,theAnalyzer); hits = searcher.search(theQuery); resultDocs = ""; System.out.println("ANDQuery: hits.length=" + hits.length()); for (int i = 0; i < hits.length(); i++) { System.out.println("ANDQuery:Doc[" + i + "]= "+ hits.doc(i).get(contentFieldName)); resultDocs += hits.doc(i).get(contentFieldName); } assertEquals("resultDocs = " + resultDocs,3, hits.length()); } public void testNOT() throws Exception { //theNOTquery should return only Doc3 String theNOTQueryS = "+(c:fruits c:vegetables) NOT (c:tomatoes c:bananas)"; assertQueryEquals(theNOTQueryS, theAnalyzer, "+(c:fruits c:vegetables) -(c:tomatoes c:bananas)"); theQuery = getQuery(theNOTQueryS,theAnalyzer); hits = searcher.search(theQuery); resultDocs = ""; System.out.println("NOTQuery: hits.length=" + hits.length()); for (int i = 0; i < hits.length(); i++) { System.out.println("NOTQuery:Doc[" + i + "]= "+ hits.doc(i).get(contentFieldName)); resultDocs += hits.doc(i).get(contentFieldName); } assertEquals("resultDocs = " + resultDocs, 1, hits.length()); } }