我试图在StringField中查询使用Lucene 4.5创建的索引,其中包含由多个术语组成的字符串。
让我们假设我们使用以下代码片段/伪代码创建一个Document对象。
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);
现在假设我使用以下查询代码查询上面的创建索引(再次只是我使用的实际代码的草图):
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);
当我运行上面的代码时,我得到了以下与searcher.search(query,1)语句相对应的异常:
Exception in thread "main" java.lang.IllegalStateException: field "Title" was
indexed without position data; cannot run PhraseQuery (term=washington)
我环顾四周,找不到克服这个问题的方法。看起来在Lucene的过去版本中,您可以将Field.Index.ANALYZED选项添加到字段创建中,但在我的情况下,我无法执行类似的操作。
有什么想法吗?
答案 0 :(得分:2)
您的查询将被分析为全文,而不是一个原子字符串。为了使查询解析器能够有效地决定用于不同字段的适当分析器,您可以使用PerFieldAnalyzerWrapper
,KeywordAnalyzer
作为适当的分析器应用于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);