You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala Mongo驱动2.1.0:Find过滤器生成Long型日期的查询问题

解决Mongo Shell中日期过滤器转为长整型的查询异常问题

我来帮你搞定这个查询异常的问题~首先得理清原因:你在Mongo Shell里使用ISODate()构造日期时,如果传入的字符串格式不完整(比如你写的"2018-04..."),Shell没法正确解析成ISODate对象,反而会把它转成长整型时间戳,导致查询无法匹配文档里的ISODate类型字段。结合你用的是mongo-scala-driver 2.1.0,我分Shell端和Scala代码端两种场景给你解决方案:

1. 修复Mongo Shell中的查询写法

确保ISODate的格式完全标准

Mongo Shell的ISODate()只认完整的ISO 8601格式字符串,比如"2018-04-30T23:59:59.999Z"。把你的查询补全格式后,就能正确识别为日期类型了:

db.getCollection('wwactivities').find({
  userId: "2c48bc64-76cd-41b0-88af-b8dfea667960",
  "activity.completedAt": { $lte: ISODate("2018-04-30T23:59:59.999Z") }
})

换用new Date()构造日期对象

如果ISODate()还是出现解析问题,直接用new Date()替代也能解决,Shell会自动识别为日期类型:

db.getCollection('wwactivities').find({
  userId: "2c48bc64-76cd-41b0-88af-b8dfea667960",
  "activity.completedAt": { $lte: new Date("2018-04-30T23:59:59.999Z") }
})

要是你已经有目标日期的时间戳(长整型),也可以直接传进去:

// 2018-04-30T23:59:59.999Z对应的时间戳是1525103999999
db.getCollection('wwactivities').find({
  userId: "2c48bc64-76cd-41b0-88af-b8dfea667960",
  "activity.completedAt": { $lte: new Date(1525103999999) }
})

2. Scala驱动端的日期处理最佳实践

既然你用的是mongo-scala-driver 2.1.0,代码里的日期处理也得规范,避免生成的查询自带“日期转Long”的坑:

  • 优先用java.time.Instant或者org.joda.time.DateTime(驱动2.x版本支持Joda时间,3.x之后转向Java 8时间API)构造日期,别直接传长整型时间戳。
  • 给你个示例代码参考:
import org.mongodb.scala._
import org.mongodb.scala.model.Filters._
import java.time.Instant

// 初始化客户端和集合
val mongoClient = MongoClient()
val database = mongoClient.getDatabase("your_database_name")
val collection = database.getCollection("wwactivities")

// 构造目标日期(完整ISO格式)
val targetCompletedAt = Instant.parse("2018-04-30T23:59:59.999Z")
// 组装查询条件
val query = and(
  equal("userId", "2c48bc64-76cd-41b0-88af-b8dfea667960"),
  lte("activity.completedAt", targetCompletedAt)
)

// 执行查询
collection.find(query).subscribe(
  doc => println(s"匹配到文档: $doc"),
  err => println(s"查询出错: ${err.getMessage}"),
  () => println("查询完成")
)

这样生成的查询会正确使用ISODate类型,不会转成Long,在Shell里查看查询日志也能看到正确的日期格式。

3. 验证过滤器的类型是否正确

你可以在Shell里先打印过滤器,确认它的类型是不是ISODate:

var filter = {
  userId: "2c48bc64-76cd-41b0-88af-b8dfea667960",
  "activity.completedAt": { $lte: ISODate("2018-04-30T23:59:59.999Z") }
}
printjson(filter)

如果输出里"activity.completedAt.$lte"的类型是ISODate("...")而不是数字,说明过滤器是对的;如果是数字,那就是日期字符串格式的问题,得重新调整格式。

内容的提问来源于stack exchange,提问作者luddy2018

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:14:18