NumericFields 使用trie结构进行索引。您看到的术语是其中的一部分,但如果您查询它们,则不会返回结果。
尝试使用 Int32.MaxValue 的精度步长索引 NumericField,这些值将消失。
NumericField 文档
...在 Lucene 中,每个数值都被索引为一个 trie 结构,其中每个术语在逻辑上分配给越来越大的预定义括号(它们只是值的低精度表示)。每个连续括号之间的步长称为precisionStep,以位为单位。较小的precisionStep 值会导致更多的括号,这会在索引中消耗更多的磁盘空间,但可能会导致更快的范围搜索性能。选择默认值 4 是为了合理权衡磁盘空间消耗与性能。如果您想更改值,可以使用专家构造函数 NumericField(String,int,Field.Store,boolean)。请注意,您还必须在创建 NumericRangeQuery 或 NumericRangeFilter 时指定一个全等值。对于低基数场,较大的精度步长是好的。如果基数 < 100,则使用 Integer.MAX_VALUE 是公平的,每个值产生一个术语。...
有关NumericRangeQuery 文档中提供的精度步骤的更多详细信息:
PrecisionStep 的良好值取决于使用情况和数据类型:
• 所有数据类型的默认值为4,当没有给出precisionStep 时使用。
• 大多数情况下,64 位数据类型(long、double)的理想值是 6 或 8。
• 大多数情况下,32 位数据类型(int、float)的理想值为 4。
• 对于低基数字段,较大的精度步长是好的。如果基数 < 100,使用 •Integer.MAX_VALUE 是公平的(见下文)。
• long/double 的步数≥64,int/float 的步数≥32,在索引中为每个值生成一个标记,查询与传统的 TermRangeQuery 一样慢。但它可用于生成仅用于排序的字段(在这种情况下,只需使用 Integer.MAX_VALUE 作为precisionStep)。使用 NumericFields 进行排序是理想的,因为构建字段缓存比使用纯文本数字快得多。这些字段每个值都有一个术语,因此也可以与术语枚举一起使用以构建不同的列表(例如要搜索的构面/预选值)。使用上述precisionSteps之一也可以对范围查询优化字段进行排序。
编辑
小样本,由此产生的索引将在卢克中显示值为 8192、9984、1792 等的术语,但使用将它们包含在查询中的范围不会产生结果:
NumericField number = new NumericField("number", Field.Store.YES, true);
Field regular = new Field("normal", "", Field.Store.YES, Field.Index.ANALYZED);
IndexWriter iw = new IndexWriter(FSDirectory.GetDirectory("C:\\temp\\testnum"), new StandardAnalyzer(), true);
Document doc = new Document();
doc.Add(number);
doc.Add(regular);
number.SetIntValue(1);
regular.SetValue("one");
iw.AddDocument(doc);
number.SetIntValue(2);
regular.SetValue("one");
iw.AddDocument(doc);
number.SetIntValue(13);
regular.SetValue("one");
iw.AddDocument(doc);
number.SetIntValue(2000);
regular.SetValue("one");
iw.AddDocument(doc);
number.SetIntValue(9999);
regular.SetValue("one");
iw.AddDocument(doc);
iw.Commit();
IndexSearcher searcher = new IndexSearcher(iw.GetReader());
NumericRangeQuery rangeQ = NumericRangeQuery.NewIntRange("number", 1, 2, true, true);
var docs = searcher.Search(rangeQ);
Console.WriteLine(docs.Length().ToString()); // prints 2
rangeQ = NumericRangeQuery.NewIntRange("number", 13, 13, true, true);
docs = searcher.Search(rangeQ);
Console.WriteLine(docs.Length().ToString()); // prints 1
rangeQ = NumericRangeQuery.NewIntRange("number", 9000, 9998, true, true);
docs = searcher.Search(rangeQ);
Console.WriteLine(docs.Length().ToString()); // prints 0
Console.ReadLine();