MongoDB如何筛选数组长度为2且第二个元素大于第一个的文档
MongoDB筛选数组元素满足条件的文档解决方法
示例文档
[ { "_id" : ObjectId("634c5167d7f84b95b91f9ba2"), "activity_id" : ObjectId("634c5167d7f84b95b91f9b9f"), "lat" : 39.9762, "lon" : 116.330383333333, "altitude" : 229.658792650919, "date_days" : 39184.4329166667, "date_time" : ISODate("2007-04-12T10:23:24.000+0000"), "altitudes" : [ 173.884514435696, 229.658792650919 ] }, { "_id" : ObjectId("634c5167d7f84b95b91f9ba3"), "activity_id" : ObjectId("634c5167d7f84b95b91f9b9f"), "lat" : 39.9760333333333, "lon" : 116.330366666667, "altitude" : 259.186351706037, "date_days" : 39184.4341319444, "date_time" : ISODate("2007-04-12T10:25:09.000+0000"), "altitudes" : [ 229.658792650919, 259.186351706037 ] } ]
需求
筛选出altitudes字段包含2个元素,且第二个元素大于第一个元素的文档。
问题分析
你之前尝试的写法均未生效,核心原因是直接用字符串'altitudes.0'作为比较值,MongoDB会将其视为普通字符串而非字段引用,无法实现数组元素间的数值比较。
解决方法
方法1:使用$expr直接在$match中比较
$expr允许在查询语句中使用聚合表达式,实现同一文档内字段的比较:
db.collection.aggregate([ { $match: { $and: [ { 'altitudes': { $size: 2 } }, { $expr: { $gt: [ { $arrayElemAt: ['$altitudes', 1] }, { $arrayElemAt: ['$altitudes', 0] } ] } } ] } } ])
$arrayElemAt: ['$altitudes', 1]获取数组的第二个元素(索引从0开始)$arrayElemAt: ['$altitudes', 0]获取数组的第一个元素$gt比较两个元素的大小,满足条件时返回true
方法2:新增标记字段后筛选
如果需要保留中间计算结果,可先通过$addFields生成标记字段,再筛选:
db.collection.aggregate([ { $match: { 'altitudes': { $size: 2 } } }, { $addFields: { isAltitudeIncreasing: { $gt: [ { $arrayElemAt: ['$altitudes', 1] }, { $arrayElemAt: ['$altitudes', 0] } ] } } }, { $match: { isAltitudeIncreasing: true } } ])
- 第一步
$match先过滤出数组长度为2的文档 $addFields新增isAltitudeIncreasing字段,标记是否满足第二个元素大于第一个- 最后
$match筛选出符合条件的文档
内容的提问来源于stack exchange,提问作者Amjad
相关产品推荐
相关产品推荐

