获得"洞"在MogoDB收集的日期

时间:2018-03-05 10:12:48

标签: mongodb

我有一个MongoDB集合,可以存储自2011年以来每小时的数据。 例如:

{ 
    "dateEntity" : ISODate("2011-01-01T08:00:00Z"), 
    "price" : 0.3
}

{ 
    "dateEntity" : ISODate("2011-01-01T09:00:00Z"), 
    "price" : 0.35
}

我想知道是否有"漏洞"在那个日期。例如,一小时缺少一个条目。

1 个答案:

答案 0 :(得分:1)

不幸的是,Mongodb中没有间隙标记聚合器。 我已经检查了是否可以通过在Map-Reduce管道中为Javascript函数编写一个自己的gap-aggregator,方法是在第一个map阶段创建一个时间栅格,然后将其映射到相应的值,但是在映射时不鼓励数据库读取并减少,所以这将是糟糕的设计。因此,使用Mongodb自己的仪器无法实现这一目标。 我认为,有两种可能的解决方案。

解决方案一:使用类似Java驱动程序的驱动程序

我建议您可以使用像Java驱动程序这样的惯用驱动程序来处理Mongodb数据,并像提供的测试一样创建一个小时的栅格。

import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoCollection;
import org.bson.Document;
import org.junit.Test;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class HourGapsTest {

    @Test
    public void testHourValues() {
        String host = "127.0.0.1:27017";
        ServerAddress addr = new ServerAddress(host);
        MongoClient mongoClient = new MongoClient(addr);
        MongoCollection<Document> collection = mongoClient.getDatabase("sotest").getCollection("hourhole");

        LocalDateTime start = LocalDateTime.of(2011, 1, 1, 8, 0, 0);
        LocalDateTime end = LocalDateTime.of(2011, 1, 2, 0, 0, 0);

        List<LocalDateTime> allHours = new ArrayList<>();

        for (LocalDateTime hour = start; hour.isBefore(end); hour = hour.plusHours(1L)) {
            allHours.add(hour);
        }

        List<LocalDateTime> gaps = new ArrayList<>();

        for (LocalDateTime hour : allHours) {
            BasicDBObject filter = new BasicDBObject("dateEntity", new Date(hour.toInstant(ZoneOffset.UTC).toEpochMilli()));
            if (!collection.find(filter).iterator().hasNext()) {
                gaps.add(hour);
            }
        }
        gaps.forEach(System.out::println);
    }

}

解决方案二:使用时间序列数据库

但是,像Kairosdb这样的时间序列数据库提供了这种功能。考虑将这些时间价值数据存储在时间序列数据库中。