我正在使用Lucene.NET 4.8.0 Beta存储一组仅包含数字数据的文档。
有两组字段。一组主要用于搜索,因此,主要用于索引。这些字段最多可以包含100个。我们称其为人口统计领域。由于字段的数量在源与源之间是可变的,但在一个源中相同,因此它们存储在数组中。
给定一组与搜索查询匹配的文档,另一组字段包含我希望读取的数据。它们也是可变的,因此存储在数组中。
我将人口统计和数据字段存储在索引中,就像这样,以便这些字段从a1 ... aN和b1 ... bM开始:
foreach (var record in records)
{
var i = 1;
foreach (var demo in record.DemographicFields)
{
var demoField = new Int32Field($"a{i}", demo, Field.Store.YES);
doc.Add(demoField);
i++;
}
var j = 1;
foreach (var data in record.Data)
{
var dataField = new Int32Field($"b{i}", data, Field.Store.YES);
doc.Add(dataField);
j++;
}
}
要查询,我加载了索引并创建了IndexSearcher,然后
var path = new DirectoryInfo("path/to/index");
var directory = new MMapDirectory(path);
using (var reader = DirectoryReader.Open(directory))
{
var searcher = new IndexSearcher(reader);
var query = BuildQuery(expression);
var collector = new SomeCollector();
searcher.Search(query, collector);
}
我真正需要做的是对一个(或多个)数据字段进行汇总,这样我就知道一个值在给定数据字段中出现多少次,例如对于与a1:[1匹配的文档10],我想获取b1中所有值的出现。
最多可以有200,000条记录。
我已经能够在ElasticSearch中执行类似的查询和聚合,但是我希望代码与数据接近,因为我需要为单个报告执行许多此类查询和聚合,而且我觉得有点局限性如何使用ElasticSearch整理数据。由于我只需要数据存储和索引功能,因此我决定直接使用Lucene是最好的方法。
我尝试使用一个收集器,该收集器读取在Collect方法中匹配的文档上的所需字段,但是我发现这很慢。
public void Collect(int doc)
{
var field = context.Reader.Document(doc).GetField($"b{index}");
var value = field.GetInt32Value();
if (value.HasValue)
{
buckets[value.Value]++;
}
}