Lucene RangeQuery没有适当过滤

我正在使用RangeQuery来获取介于0到2之间的所有文档。当我执行查询时,Lucene还给了我大于2的文档。 我在这里想念的是什么?

这是我的代码:

 Term lowerTerm = new Term("amount", minAmount); Term upperTerm = new Term("amount", maxAmount); RangeQuery amountQuery = new RangeQuery(lowerTerm, upperTerm, true); finalQuery.Add(amountQuery, BooleanClause.Occur.MUST); 

这是我的索引中的内容:

 doc.Add(new Field("amount", amount.ToString(), Field.Store.YES, Field.Index.UN_TOKENIZED, Field.TermVector.YES)); 

更新 :就像@basZero在评论中所说,从Lucene 2.9开始,您可以在文档中添加数字字段 。 只需记住在搜索时使用NumericRangeQuery而不是RangeQuery。

原始答案

Lucene将数字视为单词,因此它们的顺序是字母的:

 0 1 12 123 2 22 

这意味着对于Lucene,12介于0和2之间。如果要进行正确的数值范围,则需要对零填充的数字进行索引,然后进行[0000至0002]的范围搜索。 (您需要的填充量取决于预期的值范围)。

如果您有负数,只需为非负数添加另一个零。 (编辑: 错误错误 。请参阅更新)

如果您的数字包含小数部分,请保持原样,并仅对整数部分进行零填充。

例:

 -00002.12 -00001 

 000000 000001 000003.1415 000022 

更新 :负数有点棘手,因为-1按字母顺序排在-2之前。 本文给出了关于在Lucene中处理负数和数字的完整解释。 基本上,你必须将数字“编码”成一些使得项目顺序有意义的东西。

我创建了一个PHP函数,将数字转换为lucene / solr范围的可搜索值。

0.5转换为10000000000.5
-0.5转换为09999999999.5

 function luceneNumeric($numeric) { $negative = $numeric < 0; $numeric = $negative ? 10000000000 + $numeric : $numeric; $parts = explode('.', str_replace(',', '.', $numeric)); $lucene = $negative ? 0 : 1; $lucene .= str_pad($parts[0], 10, '0', STR_PAD_LEFT); $lucene .= isset($parts[1]) ? '.' . $parts[1] : ''; return $lucene; } 

它似乎工作,希望这有助于某人!