MongoDB:在arrayFilters中使用日期比较时出现$lt操作符错误如何解决?
问题描述
我的集合中文档包含citizens字段,是一个对象数组,数组内的对象有字符串类型的birthday字段,示例数据如下:
{ citizens: [{ name: 'John', birthday: '1993/07/13' }, { name: 'Sarah', birthday: '1996/07/13' }, { name: 'Natalia', birthday: '2015/07/13' }] } { citizens: [{ name: 'Leo', birthday: '1994/02/08' }, { name: 'Paul', birthday: '1934/09/13' }, { name: 'Rego', birthday: '2019/01/29' }] }
我想给所有年满18岁的用户添加status: 'adult',尝试执行以下代码:
users.updateMany({}, { $set: { 'citizens.$[elem].status': 'adult' }, }, { arrayFilters: [ { 'elem.status': { $exists: false } }, { $lt: [{ $toDate: 'elem.$birthday' }, 18yearsaAgoDate] }, // 此处18years仅为示例,实际使用$$NOW ], multi: true, });
运行时报错:unknown top level operator: $lt,请问怎么在arrayFilter里正确使用$lt操作符?
解决方案
报错核心是arrayFilters的语法错误:
- 每个数组过滤条件必须是以字段为键的对象,不能直接把
$lt作为顶层键; - 引用数组元素的字段时,要使用
$$前缀(比如$$elem.birthday),而非elem.$birthday; - 计算18年前的日期,直接用MongoDB的日期操作符
$dateSubtract配合系统变量$$NOW即可,无需提前定义变量。
正确代码示例
users.updateMany({}, { $set: { 'citizens.$[elem].status': 'adult' } }, { arrayFilters: [ { 'elem.status': { $exists: false } }, { '$$elem.birthday': { $lt: { $dateToString: { format: "%Y/%m/%d", date: { $dateSubtract: { startDate: "$$NOW", unit: "year", amount: 18 } } } } } } ], multi: true } );
关键细节说明
- 因为
birthday是YYYY/MM/DD格式的字符串,所以需要把计算出的18年前日期也转换成相同格式的字符串,才能用$lt做正确比较; $$elem是arrayFilters里定义的占位符,对应数组中的每个待校验元素;$dateSubtract从当前时间($$NOW)减去18年得到目标日期,再通过$dateToString统一格式,确保比较逻辑准确。
兼容低版本MongoDB(4.2以下)的写法
如果你的MongoDB版本不支持$dateSubtract,可以用时间戳近似计算(注意:未考虑闰年,适合精度要求不高的场景):
{ '$$elem.birthday': { $lt: { $dateToString: { format: "%Y/%m/%d", date: { $toDate: { $subtract: ["$$NOW", 18 * 365 * 24 * 60 * 60 * 1000] } } } } } }
内容的提问来源于stack exchange,提问作者Fruling
相关产品推荐
相关产品推荐

