(纯)Lucene:计算longfield中有时间戳的文档,按年份分组

(纯)Lucene:计算longfield中有时间戳的文档,按年份分组,lucene,range,facet,faceted-search,Lucene,Range,Facet,Faceted Search,我的文件结构是: [文本:TextField,日期:LongField] 我正在根据dateTime字段的精度级别,对我的文档进行“统计”查询。这意味着计算按LongField日期分组的文档,忽略日期右侧的一些字节 对于给定的精度,我要查找多少文档与此精度的每个不同值相匹配 假设精度“年”按“日期/10000”分组 使用以下数据: {text:"text1",dateTime:(some timestamp where year is 2015 like 20150000)} {text:"te

我的文件结构是: [文本:TextField,日期:LongField]

我正在根据dateTime字段的精度级别,对我的文档进行“统计”查询。这意味着计算按LongField日期分组的文档,忽略日期右侧的一些字节

对于给定的精度,我要查找多少文档与此精度的每个不同值相匹配

假设精度“年”按“日期/10000”分组 使用以下数据:

{text:"text1",dateTime:(some timestamp where year is 2015 like 20150000)}
{text:"text2",dateTime:(some timestamp where year is 2010 like 20109878)} 
{text:"text3",dateTime:(some timestamp where year is 2015 like 20150024)} 
{text:"text14,dateTime:(some timestamp where year is 1997 like 19970987)}  
结果应该是:

[{bracket:1997, count:1}
{bracket:2010, count:1}
{bracket:2015, count:2}]
虽然NumericRangeQuery允许创建1个(或一些)范围,但lucene是否可以基于精度步长生成范围

我可以通过为我需要的每一个精度级别创建一个新字段来处理这个问题,但也许这种东西allready是存在的

这是一种分面搜索,其中分面是时间。用例应该是:

-give me document count for each milleniums,
-then give me document count for each centuries (inside a millenium)
-then give me document count for each year (inside a century)
-then give me document count for each days (inside a year)
当bucket中存在0个文档时,结果不应出现在结果中


关于

收集器可以无需任何技巧即可完成此操作,以下是工作代码:

    public class GroupByTest1 {
    private RAMDirectory directory;
    private IndexSearcher searcher;
    private IndexReader reader;
    private Analyzer analyzer;

    private class Data {
        String text;
        Long dateTime;

        private Data(String text, Long dateTime) {
            this.text = text;
            this.dateTime = dateTime;
        }
    }

    @Before
    public void setUp() throws Exception {
        directory = new RAMDirectory();

        analyzer = new WhitespaceAnalyzer();
        IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(analyzer));
        Data datas[] = {
                new Data("A", 2012L),
                new Data("B", 2012L),
                new Data("C", 2012L),
                new Data("D", 2013L),
        };

        Document doc = new Document();
        for (Data data : datas) {
            doc.clear();
            doc.add(new TextField("text", data.text, Field.Store.YES));
            doc.add(new LongField("dateTime", data.dateTime, Field.Store.YES));
            writer.addDocument(doc);
        }
        writer.close();

        reader = DirectoryReader.open(directory);
        searcher = new IndexSearcher(reader);
    }


    @Test
    public void test1() throws Exception {
        final Map<Integer, Long> map = new HashMap<>();
        Collector collector = new SimpleCollector() {
            int base = 0;

            @Override
            public void collect(int doc) throws IOException {
                String year = reader.document(doc + base).get("dateTime");
                if (!map.containsKey(Integer.valueOf(year))) {
                    map.put(Integer.valueOf(year), 1L);
                } else {
                    long l = map.get(Integer.valueOf(year));
                    map.put(Integer.valueOf(year), ++l);
                }
            }

            @Override
            public boolean needsScores() {
                return false;
            }

            @Override
            protected void doSetNextReader(LeafReaderContext context) throws IOException {
                base = context.docBase;
            }
        };
        searcher.search(new MatchAllDocsQuery(), collector);
        for (Integer integer : map.keySet()) {
            System.out.print("year = " + integer);
            System.out.println(" count = " + map.get(integer));
        }
    }
}

这可能运行缓慢,具体取决于您有多少条记录。它加载每个文档,以了解其上的年份以及基于该年份的组。还有一个分组模块,您也可以查看它

给我们一些您想要运行的示例查询,您的查询语句是抽象的。如果您希望今年有单据,则对今年进行范围查询,并获取其中的数量;如果您按月进行,则再次对月份进行范围查询。如果范围查询不足以让我的帖子澄清我的请求,请提供更多详细信息。事实上,我不能指定日期值,而是返回所有现有的differts-dates值,以特定的精度级别,每个bucket中的文档数。尊敬。您的示例在某个特定日期(2012年)执行此技巧。假设您不知道数据库的内容,并且需要计算dateTime字段中每个不同年份的文档数。Thanksit还向您展示了如何获取特定月份(样本中为2013年2月)的信息,您可以不断缩小范围。它不希望使用特定日期。我需要生成以下统计信息=>统计dateTime字段值内的每个不同年份的文档。您可以这样使用日期:20150101表示年初,20151231表示年末。因此,20150101-20151231的范围查询将给出2015年的所有单据。
year = 2012 count = 3
year = 2013 count = 1