1   package org.marketchangers.prayer.lucene;
2   
3   import java.io.IOException;
4   import java.text.SimpleDateFormat;
5   import java.util.Date;
6   
7   import junit.framework.TestCase;
8   
9   import org.apache.lucene.analysis.Analyzer;
10  import org.apache.lucene.analysis.standard.StandardAnalyzer;
11  import org.apache.lucene.document.DateField;
12  import org.apache.lucene.document.Document;
13  import org.apache.lucene.document.Field;
14  import org.apache.lucene.index.IndexWriter;
15  import org.apache.lucene.index.Term;
16  import org.apache.lucene.queryParser.MultiFieldQueryParser;
17  import org.apache.lucene.queryParser.ParseException;
18  import org.apache.lucene.search.BooleanQuery;
19  import org.apache.lucene.search.DateFilter;
20  import org.apache.lucene.search.FilteredQuery;
21  import org.apache.lucene.search.IndexSearcher;
22  import org.apache.lucene.search.Query;
23  import org.apache.lucene.search.RangeQuery;
24  import org.apache.lucene.search.Searcher;
25  import org.apache.lucene.search.TermQuery;
26  import org.apache.lucene.store.Directory;
27  import org.apache.lucene.store.RAMDirectory;
28  
29  /***
30   * @author <a href="mailto:mtodd@wc-group.com">Matthew Todd</a>
31   */
32  public class LearningTest extends TestCase {
33  	public void testNewRamDirectoriesHaveNoFiles() {
34  		assertEquals(0, new RAMDirectory().list().length);
35  	}
36  
37  	public void testWrittenDirectoriesHaveSomeFiles() throws IOException {
38  		Directory directory = new RAMDirectory();
39  		new IndexWriter(directory, new StandardAnalyzer(), true).close();
40  		assertTrue(0 < directory.list().length);
41  	}
42  
43  	public void testCannotKeepAnIndexSearcherAcrossWritings()
44  		throws IOException {
45  		Directory directory = new RAMDirectory();
46  
47  		IndexWriter writer;
48  		writer = new IndexWriter(directory, new StandardAnalyzer(), true);
49  		writer.close();
50  
51  		Searcher searcher = new IndexSearcher(directory);
52  		assertEquals(0, searcher.maxDoc());
53  
54  		Document document = new Document();
55  		document.add(Field.Keyword("the man", "Jianshuo"));
56  		writer = new IndexWriter(directory, new StandardAnalyzer(), false);
57  		writer.addDocument(document);
58  		writer.close();
59  
60  		assertEquals(0, searcher.maxDoc());
61  		assertEquals(1, new IndexSearcher(directory).maxDoc());
62  	}
63  
64  	public void testTheDirectoryIsNotModifiedUntilClose() throws IOException {
65  		Directory directory = new RAMDirectory();
66  		IndexWriter writer;
67  
68  		Document document = new Document();
69  		document.add(Field.Keyword("the man", "Jianshuo"));
70  		writer = new IndexWriter(directory, new StandardAnalyzer(), true);
71  		writer.addDocument(document);
72  
73  		assertEquals(0, new IndexSearcher(directory).maxDoc());
74  		writer.close();
75  		assertEquals(1, new IndexSearcher(directory).maxDoc());
76  	}
77  
78  	public void testMultiFieldQueryParserWithEmptyStringExplodes() {
79  		try {
80  			MultiFieldQueryParser.parse("", "field", new StandardAnalyzer());
81  			fail("We thought this would throw an Exception.");
82  		} catch (ParseException pe) {
83  			// expected
84  		}
85  	}
86  
87  	public void testMultiFieldQueryParserWithStarWorks() throws Exception {
88  		MultiFieldQueryParser.parse("a*", "field", new StandardAnalyzer());
89  	}
90  
91  	public void testDateRangeSearchesWithFilteredQueries() throws Exception {
92  		Directory directory = new RAMDirectory();
93  		Analyzer analyzer = new StandardAnalyzer();
94  
95  		Document entry = new Document();
96  		entry.add(Field.Keyword("date", date("08-19-2004")));
97  		entry.add(Field.Keyword("anything", "anything"));
98  
99  		IndexWriter writer = new IndexWriter(directory, analyzer, true);
100 		writer.addDocument(entry);
101 		writer.close();
102 
103 		IndexSearcher searcher = new IndexSearcher(directory);
104 		Query query = dateAfterQuery("08-20-2004");
105 
106 		assertEquals(0, searcher.search(query).length());
107 		query = dateAfterQuery("08-19-2004");
108 		assertEquals(1, searcher.search(query).length());
109 		query = dateAfterQuery("08-18-2004");
110 		assertEquals(1, searcher.search(query).length());
111 	}
112 
113 	private Query anythingQuery() {
114 		return new TermQuery(new Term("anything", "anything"));
115 	}
116 
117 	private Date date(String date) throws Exception {
118 		return new SimpleDateFormat("MM-dd-yyyy").parse(date);
119 	}
120 
121 	private DateFilter dateAfter(String date) throws Exception {
122 		return DateFilter.After("date", date(date));
123 	}
124 
125 	private FilteredQuery dateAfterQuery(String date) throws Exception {
126 		return new FilteredQuery(anythingQuery(), dateAfter(date));
127 	}
128 
129 	private Query alternativeDateAfterQuery(String date) throws Exception {
130 		return new RangeQuery(
131 			new Term("date", DateField.dateToString(date(date))),
132 			null,
133 			true);
134 	}
135 
136 	public void testBooleanFilteredQueriesDontWorkSoWell() throws Exception {
137 		Directory directory = new RAMDirectory();
138 		Analyzer analyzer = new StandardAnalyzer();
139 
140 		Document entry = new Document();
141 		entry.add(Field.Keyword("date", date("08-19-2004")));
142 		entry.add(Field.Keyword("anything", "anything"));
143 
144 		IndexWriter writer = new IndexWriter(directory, analyzer, true);
145 		writer.addDocument(entry);
146 		writer.close();
147 
148 		IndexSearcher searcher = new IndexSearcher(directory);
149 
150 		// First try: boolean(dateAfterQuery + anythingQuery)
151 		BooleanQuery query = new BooleanQuery();
152 		query.add(dateAfterQuery("08-20-2004"), true, false);
153 		assertEquals(0, searcher.search(query).length());
154 		query.add(anythingQuery(), true, false);
155 		// Hoped for 0; we thought dateAfterQuery was absolutely required.
156 		assertEquals(1, searcher.search(query).length());
157 
158 		// Second try: filter(boolean(anythingQuery), dateAfter)
159 		query = new BooleanQuery();
160 		query.add(anythingQuery(), true, false);
161 		assertEquals(1, searcher.search(query).length());
162 		// Yes!
163 		assertEquals(
164 			0,
165 			searcher.search(query, dateAfter("08-20-2004")).length());
166 
167 		// Aside: BooleanQuery without dates.
168 		query = new BooleanQuery();
169 		query.add(
170 			new TermQuery(new Term("anything", "something else")),
171 			true,
172 			false);
173 		assertEquals(0, searcher.search(query).length());
174 		query.add(anythingQuery(), true, false);
175 		assertEquals(0, searcher.search(query).length());
176         
177         // Third try: boolean(alternativeDateAfterQuery + anythingQuery)
178         query = new BooleanQuery();
179         query.add(alternativeDateAfterQuery("08-20-2004"), true, false);
180         assertEquals(0, searcher.search(query).length());
181         query.add(anythingQuery(), true, false);
182         assertEquals(0, searcher.search(query).length());        
183 	}
184 }