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

Java 如何查找在两个LocalDateTime之间插入的所有MongoDB文档,java,mongodb,datetime,Java,Mongodb,Datetime,我正在尝试开发一个应用程序,可以检索在特定时间段内插入的所有文档 这是我的实际示例代码: MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017"); MongoDatabase database = mongoClient.getDatabase("eam"); MongoCollection<Document> collection = database.getCollection("col

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

这是我的实际示例代码:

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();
}
MongoClient MongoClient=MongoClients.create(“mongodb://localhost:27017");
MongoDatabase=mongoClient.getDatabase(“eam”);
MongoCollection collection=database.getCollection(“coll”);
List docsList=new ArrayList();
LocalDateTime initDate=LocalDateTime.now();
LocalDateTime endDate=initDate.plusSeconds(5);
int i=0;
while(LocalDateTime.now().isBefore(endDate)){
文档文档=新文档(“id”,i)
.append(“名称objy”、“Obj”+i)
.append(“timeStamp”,LocalDateTime.now());
docsList.add(doc);
i++;
}
集合。插入多个(docsList);
MongoCursor=collection.find(新文档(“时间戳”,新文档($gte),endDate.minusSeconds(3)).append($lte,endDate.minusSeconds(2))).iterator();
试一试{
while(cursor.hasNext()){
System.out.println(cursor.next().toJson());
}
}最后{
cursor.close();
}
作为@Valijo,我修改了我的代码以通过gte和lte进行过滤,但现在它没有返回任何内容! 为什么?

如果不想使用时间戳,请查看

$in检查时间戳是否等于$in中的一个值:

但您需要一个中间人,此代码应适用于您:

 db.yourcollection.find({$gte: {'timestamp': min}, $lte: {'timestamp': max}})
请注意:上面的代码是针对MongoShell的,但您应该能够将其“翻译”为所需的语法

编辑:还请注意,mongodbs时间始终是UTC

如果您不想使用时间戳,请查看一下

$in检查时间戳是否等于$in中的一个值:

但您需要一个中间人,此代码应适用于您:

 db.yourcollection.find({$gte: {'timestamp': min}, $lte: {'timestamp': max}})
请注意:上面的代码是针对MongoShell的,但您应该能够将其“翻译”为所需的语法


编辑:还请注意,mongodbs时间始终为UTC

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

因此,您需要保留准确的
时间戳
参考(精度为1ms)

问题在于:

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++;
}
然后您的查询将返回您期望的结果

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

保留
时间戳
引用,然后搜索它们

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")
}
因此,数据库中不存在2018年9月20日星期四15:28:56.014


解决方案3:不要使用精确值匹配,使用
$gte
$lte
操作符搜索
时间戳
范围

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

因此,您需要保留准确的
时间戳
参考(精度为1ms)

问题在于:

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++;
}
然后您的查询将返回您期望的结果

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

保留
时间戳
引用,然后搜索它们

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")
}
因此,数据库中不存在2018年9月20日星期四15:28:56.014

解决方案3:不要使用精确值匹配,而是使用
$gte
$lte
运营商搜索
时间戳
范围