2011-03-01 85 views
4

我刚刚开始使用Lucene,我觉得我必须对它有一个基本的误解,但是从样本和文档中我找不到这个问题。在Lucene中搜索TokenStream字段

我似乎无法让Lucene返回使用TokenStream初始化的字段的结果,而使用string初始化的字段正常工作。我正在使用Lucene.NET 2.9.2 RC2。

[编辑]我也试过用最新的Java版本(3.0.3),并看到相同的行为,所以它不是一些怪异的端口。

这是一个基本的例子:

Directory index = new RAMDirectory(); 
Document doc = new Document(); 
doc.Add(new Field("fieldName", new StandardTokenizer(new StringReader("Field Value Goes Here")))); 
IndexWriter iw = new IndexWriter(index, new StandardAnalyzer()); 
iw.AddDocument(doc); 
iw.Commit(); 
iw.Close(); 
Query q = new QueryParser("fieldName", new StandardAnalyzer()).Parse("value"); 
IndexSearcher searcher = new IndexSearcher(index, true); 
Console.WriteLine(searcher.Search(q).Length()); 

(我知道这与使用2.9弃用的API,但是这只是为了简洁...假装指定版本的论点在那里,我用的一个新的Search s)。

这不会返回任何结果。

不过,如果我更换与

doc.Add(new Field("fieldName", "Field Value Goes Here", Field.Store.NO, Field.Index.ANALYZED)); 

则该查询返回的命中增加的领域,如我所期望的线路。如果我使用TextReader版本,它也可以。

这两个领域的索引和标记,与(我认为)相同的标记器/分析器(我也试过其他人),并且都不存储,所以我的直觉是,他们应该表现相同。我错过了什么?

回答

1

我发现答案是套管。

StandardAnalyzer创建的令牌流具有LowerCaseFilter,而直接创建StandardTokenizer不会应用此类过滤器。

+0

不仅如此,StandardAnalyzer还可以通过StopFilter过滤掉常见的英语StopWords。使用Lucene的经验法则是在两侧使用完全相同的TokenStream设置进行搜索和索引。在你的代码中,你不应该直接实例化StandardTokenizer,而是使用StandardAnalyzer.TokenStream()来创建它 –