Reputation: 113
I'm trying to query a StringField for an index created with Lucene 4.5 with a string made up of multiple terms.
Let us suppose we create a Document object using the following code snippet/pseudocode.
Directory dir = FSDirectory.open(new File(indexPath));
Analyzer analyzer = new EnglishAnalyzer(Version.LUCENE_45);
IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_45, analyzer);
iwc.setOpenMode(OpenMode.CREATE);
IndexWriter writer = (dir, iwc);
Document doc = new Document();
Field title = new StringField("Title", minQuery, Field.Store.YES);
doc.add(title);
writer.addDocument(doc);
Now suppose I go and query the above create index using the following query code (again is just a sketch of the actual code I'm using):
IndexReader reader = DirectoryReader.open(FSDirectory.open(new File(indexPath)));
BM25Similarity bm25sim = new BM25Similarity();
IndexSearcher searcher = new IndexSearcher(reader);
searcher.setSimilarity(bm25sim);
Analyzer analyzer = new EnglishAnalyzer(Version.LUCENE_45);
QueryParser parser = new QueryParser(Version.LUCENE_45, "Content", analyzer);
Query query = parser.parse("Title:\"washington dc\"");
TopDocs result = searcher.search(query, 1);
When I run the code above I got the following exception in correspondence of the searcher.search(query,1) statement:
Exception in thread "main" java.lang.IllegalStateException: field "Title" was
indexed without position data; cannot run PhraseQuery (term=washington)
I've looked around and I cannot find a way to overcome to this issue. It looks like in past versions of Lucene you could add the Field.Index.ANALYZED option to the field creation but I've not been able to do something like that in my case.
Any idea?
Upvotes: 0
Views: 1256
Reputation: 33341
Your query is getting analyzed as full-text, rather than as one atomic string. In order to allow the query parser to effectively decide on the appropriate analyzer to use for different fields, you can use a PerFieldAnalyzerWrapper
, with KeywordAnalyzer
being the appropriate analyzer to apply to a StringField
.
Map<String,Analyzer> analyzerMap = new HashMap<String,Analyzer>();
analyzerPerField.put("Title", new KeywordAnalyzer());
PerFieldAnalyzerWrapper analyzer =
new PerFieldAnalyzerWrapper(new EnglishAnalyzer(Version.LUCENE_45), analyzerMap);
QueryParser parser = new QueryParser(Version.LUCENE_45, "Content", analyzer);
Upvotes: 2