我正在使用Lucene 4.1来索引关键字/值对,其中关键字和值不是真实的单词 - 即,它们是不应被分析或标记化的电压,设置。例如$ P14R / 16777216.(这是任何Flow Cytometrists的FCS数据)
对于索引,我创建了一个IndexType = true,stored = true和 tokenized = false 的FieldType。这些模仿来自Lucene 1的古代Field.Keyword,我有这本书。 :-)我甚至冻结了fieldType。
我在调试器中看到了这些值。我创建了文档和索引。
当我阅读索引和文档并查看调试器中的Fields时,我会看到所有字段。名称和fieldsData看起来正确。但是,FieldType是错误的。它显示indexed = true,stored = true和 tokenized = true 。结果是我的搜索(使用TermQuery)不起作用。
我该如何解决这个问题?感谢。
P.S。我在IndexWriterConfig中使用KeywordAnalyzer。我稍后会尝试发布一些演示代码,但这是我今天真正的工作。 : - )
演示代码:
public class LuceneDemo {
public static void main(String[] args) throws IOException {
Directory lDir = new RAMDirectory();
Analyzer analyzer = new KeywordAnalyzer();
IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_41, analyzer);
iwc.setOpenMode(OpenMode.CREATE);
IndexWriter writer = new IndexWriter(lDir, iwc);
// BTW, Lucene, anyway you could make this even more tedious???
// ever heard of builders, Enums, or even old fashioned bits?
FieldType keywordFieldType = new FieldType();
keywordFieldType.setStored(true);
keywordFieldType.setIndexed(true);
keywordFieldType.setTokenized(false);
Document doc = new Document();
doc.add(new Field("$foo", "$bar123", keywordFieldType));
doc.add(new Field("contents", "$foo=$bar123", keywordFieldType));
doc.add(new Field("$foo2", "$bar12345", keywordFieldType));
Field onCreation = new Field("contents", "$foo2=$bar12345", keywordFieldType);
doc.add(onCreation);
System.out.println("When creating, the field's tokenized is " + onCreation.fieldType().tokenized());
writer.addDocument(doc);
writer.close();
IndexReader reader = DirectoryReader.open(lDir);
Document d1 = reader.document(0);
Field readBackField = (Field) d1.getFields().get(0);
System.out.println("When read back the field's tokenized is " + readBackField.fieldType().tokenized());
IndexSearcher searcher = new IndexSearcher(reader);
// exact match works
Term term = new Term("$foo", "$bar123" );
Query query = new TermQuery(term);
TopDocs results = searcher.search(query, 10);
System.out.println("when searching for : " + query.toString() + " hits = " + results.totalHits);
// partial match fails
term = new Term("$foo", "123" );
query = new TermQuery(term);
results = searcher.search(query, 10);
System.out.println("when searching for : " + query.toString() + " hits = " + results.totalHits);
// wildcard search works
term = new Term("contents", "*$bar12345" );
query = new WildcardQuery(term);
results = searcher.search(query, 10);
System.out.println("when searching for : " + query.toString() + " hits = " + results.totalHits);
}
}
输出将是:
When creating, the field's tokenized is false
When read back the field's tokenized is true
when searching for : $foo:$bar123 hits = 1
when searching for : $foo:123 hits = 0
when searching for : contents:*$bar12345 hits = 1
答案 0 :(得分:0)
您可以尝试将KeywordAnalyzer用于您不想标记的字段。
如果您需要多个分析器(即,如果您有其他需要标记化的字段),PerFieldAnalyzerWrapper就是这样。
答案 1 :(得分:0)
演示代码证明,当您阅读它时,tokenized的值会有所不同。不确定这是不是一个错误。
但这并不是部分搜索不起作用的原因。部分搜索不起作用,因为Lucene不进行部分搜索(除非您使用通配符),例如Says so here in StackOverflow
我一直在使用谷歌,我想我不明白。 : - )
答案 2 :(得分:0)
Lucene以小写存储所有令牌 - 因此,您需要先将搜索字符串转换为小写字母,以用于非标记化字段。