我有一个MongoDB集合,可以存储自2011年以来每小时的数据。 例如:
{
"dateEntity" : ISODate("2011-01-01T08:00:00Z"),
"price" : 0.3
}
{
"dateEntity" : ISODate("2011-01-01T09:00:00Z"),
"price" : 0.35
}
我想知道是否有"漏洞"在那个日期。例如,一小时缺少一个条目。
答案 0 :(得分:1)
不幸的是,Mongodb中没有间隙标记聚合器。 我已经检查了是否可以通过在Map-Reduce管道中为Javascript函数编写一个自己的gap-aggregator,方法是在第一个map阶段创建一个时间栅格,然后将其映射到相应的值,但是在映射时不鼓励数据库读取并减少,所以这将是糟糕的设计。因此,使用Mongodb自己的仪器无法实现这一目标。 我认为,有两种可能的解决方案。
我建议您可以使用像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这样的时间序列数据库提供了这种功能。考虑将这些时间价值数据存储在时间序列数据库中。