如何找到两个LocalDateTime之间插入的所有MongoDB文档

时间:2018-09-20 14:34:10

标签: java mongodb datetime

我正在尝试开发一个应用程序,以检索在一定时期内插入的所有文档。

这是我的实际示例代码:

MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
MongoDatabase database = mongoClient.getDatabase("eam");
MongoCollection<Document> collection = database.getCollection("coll");

List<Document> docsList = new ArrayList<>();

LocalDateTime initDate = LocalDateTime.now();
LocalDateTime endDate = initDate.plusSeconds(5);
int i = 0;
while (LocalDateTime.now().isBefore(endDate)) {
    Document doc = new Document("id", i)
            .append("name objy", "Obj " + i)
            .append("timeStamp", LocalDateTime.now());
    docsList.add(doc);
    i++;
}

collection.insertMany(docsList);

MongoCursor<Document> cursor = collection.find(new Document("timestamp", new Document("$gte", endDate.minusSeconds(3)).append("$lte", endDate.minusSeconds(2)))).iterator();
try {
    while (cursor.hasNext()) {
        System.out.println(cursor.next().toJson());
    }
} finally {
    cursor.close();
}

作为@Valijo,我修改了代码以按gte和lte进行过滤,但是现在它什么也没有返回! 为什么?

2 个答案:

答案 0 :(得分:2)

如果您不想使用时间戳记,请查看https://docs.mongodb.com/manual/reference/method/Date/

$ in检查时间戳是否等于$ in中的值之一:https://docs.mongodb.com/manual/reference/operator/query/in/

但是您需要一个介于两者之间的代码,此代码应该对您有用:

 db.yourcollection.find({$gte: {'timestamp': min}, $lte: {'timestamp': max}})

请注意:以上代码用于mongo shell,但是您应该能够将其“翻译”为所需的语法

编辑:还请记住,mongodbs时间始终是UTC

答案 1 :(得分:1)

$in选择给定数组的精确值。

因此,您需要保留准确的timestamp参考(精度为1毫秒)

问题在这里:

LocalDateTime initDate = LocalDateTime.now();
LocalDateTime endDate = initDate.plusSeconds(5);
int i = 0;
while (LocalDateTime.now().isBefore(endDate)) { 
    Document doc = new Document("id", i)
            .append("name objy", "Obj " + i)
            .append("timeStamp", LocalDateTime.now()); //<-- The timestamp ms may differ from initDate ms
    docsList.add(doc);
    i++;
}

解决方案1:插入文档时,请使用:

initDate.plusSeconds(i)

然后您的查询将返回您期望的结果

解决方案2:(您可以翻译成您的编程语言)

保留timeStamp个引用,然后进行搜索

var date1 = new Date(1537457334015); //Thursday, 20 September 2018 15:28:54.015
var date2 = new Date(1537457335014); //Thursday, 20 September 2018 15:28:55.014

var date3 = new Date(1537457336015); //Thursday, 20 September 2018 15:28:56.015 1 sec 1 ms
var date4 = new Date(1537457336025); //Thursday, 20 September 2018 15:28:56.025 2 sec 11 ms 

var date2Plus1Sec = new Date( date2.getTime() + 1000 );

//db.coll.remove({})

db.coll.insert([
    {
        "timeStamp" : date1
    },
    {
        "timeStamp" : date2
    },
    {
        "timeStamp" : date3
    },
    {
        "timeStamp" : date4
    }
])

db.coll.find({"timeStamp" :{$in: [date1, date2, date2Plus1Sec ]} } ).pretty();

结果:

/* 1 */
{
    "_id" : ObjectId("5ba3bea3ba135b198e17ec2d"),
    "timeStamp" : ISODate("2018-09-20T15:28:54.015Z")
}

/* 2 */
{
    "_id" : ObjectId("5ba3bea3ba135b198e17ec2e"),
    "timeStamp" : ISODate("2018-09-20T15:28:55.014Z")
}

因此Thursday, 20 September 2018 15:28:56.014在数据库中不存在

解决方案3::不要使用精确值匹配,而要使用$gte$lte运算符来搜索timeStamp范围