MongoDB嵌套数组按日期过滤失效问题求助
MongoDB嵌套数组日期过滤失效问题解决
问题场景
现有如下结构的嵌套数组文档:
[ { "id": 1, "data": [ [ ISODate("2000-01-01T00:00:00Z"), 2, 3 ], [ ISODate("2000-01-03T00:00:00Z"), 2, 3 ], [ ISODate("2000-01-05T00:00:00Z"), 2, 3 ] }, { "id": 2, "data": [] } ]
data是数组的数组,每个子数组第一个元素为日期类型。尝试用以下聚合管道过滤data中日期大于指定日期的元素:
db.collection.aggregate([ { "$match": { "id": 1 } }, { "$project": { "data": { "$filter": { "input": "$data", "as": "entry", "cond": { "$gt": [ "$$entry.0", ISODate("2000-01-04T00:00:00Z") ] } } } } } ])
出现异常:使用$gt时data返回空数组;使用$lt时返回全部元素,过滤功能完全失效。
期望结果:
[ { "id": 1, "data": [ [ ISODate("2000-01-05T00:00:00Z"), 2, 3 ] ] } ]
解决方法
问题根源在于数组元素的访问方式错误:MongoDB聚合表达式中不能直接用$$entry.0访问数组第一个元素,需使用$arrayElemAt操作符提取指定索引的元素。
修改后的聚合管道:
db.collection.aggregate([ { "$match": { "id": 1 } }, { "$project": { "data": { "$filter": { "input": "$data", "as": "entry", "cond": { "$gt": [ { "$arrayElemAt": ["$$entry", 0] }, ISODate("2000-01-04T00:00:00Z") ] } } } } } ])
原理说明
$arrayElemAt操作符用于从数组中提取指定索引位置的元素,{ "$arrayElemAt": ["$$entry", 0] }即获取每个data子数组的第一个元素(日期值)。- 替换原错误写法后,
$gt可正确比较日期大小,实现预期过滤效果。
内容的提问来源于stack exchange,提问作者Tobias S.
相关产品推荐
相关产品推荐

