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

MongoDB查询任意日期8-18点UTC时间记录报错及实现问题

问题原因

你写的查询报错是因为$expr运算符仅支持传入单个聚合表达式作为入参,直接在$expr对象下平级放置$gte、$lte两个表达式字段不符合MongoDB聚合语法规则,多条件并列判断需要通过$and运算符包裹所有条件。

原生MongoDB查询写法

正确的查询语句如下,注意$hour默认返回UTC时间的0-23格式小时值,和你存储的UTC时间格式直接匹配:

db.你的集合名.find({
  $expr: {
    $and: [
      { $gte: [ { $hour: "$DateTime" }, 8 ] },
      { $lte: [ { $hour: "$DateTime" }, 18 ] }
    ]
  }
})

如果后续需要按指定时区计算小时(比如东八区业务时间),可以给$hour传入时区参数即可:

// 按东八区时间计算小时范围
{ $hour: { date: "$DateTime", timezone: "Asia/Shanghai" } }
.NET Core 环境实现方案

首先确保项目已安装官方MongoDB.Driver NuGet包,提供两种常用实现方式:

1. 稳定通用写法(兼容所有驱动版本)

通过FilterDefinitionBuilder结合Expr方法构建查询,不需要依赖驱动的Linq翻译能力:

// 初始化集合实例
var collection = db.GetCollection<你的实体类>("你的集合名");
// 构建提取小时的公共表达式
var getHourExpr = new BsonDocument("$hour", "$DateTime");
// 组合查询条件
var filter = Builders<你的实体类>.Filter.And(
    Builders<你的实体类>.Filter.Expr(new BsonDocument("$gte", new BsonArray { getHourExpr, 8 })),
    Builders<你的实体类>.Filter.Expr(new BsonDocument("$lte", new BsonArray { getHourExpr, 18 }))
);
// 执行查询
var queryResult = await collection.Find(filter).ToListAsync();

2. Lambda强类型写法(推荐2.18.0+版本驱动使用)

高版本MongoDB驱动支持自动将DateTime的Hour属性访问翻译成$hour聚合表达式,写法和普通Linq查询完全一致:

var queryResult = await collection.AsQueryable()
    .Where(x => x.DateTime.Hour >= 8 && x.DateTime.Hour <= 18)
    .ToListAsync();
性能优化提示

上述写法都属于运行时计算字段的查询,无法命中集合索引,数据量较大时查询延迟会明显升高。如果该查询是高频场景,建议在文档中额外冗余一个DateTimeHour字段,存储对应记录UTC时间的小时数值,给该字段创建升序索引后直接按字段范围匹配,性能会有数量级提升。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 22:15:45