MongoDB中多字段范围值与指定范围的交集查询实现
MongoDB中多字段范围值与指定范围的交集查询实现
嘿,我来帮你搞定这个MongoDB的多范围交集查询问题!首先咱们得理清一个核心逻辑:两个区间[Start1, End1]和[Start2, End2]存在交集的判定条件是:Start1 <= End2 AND Start2 <= End1。只要把这个逻辑套用到你每个字段组(Room、Pool、Floor)上,就能轻松筛选出符合要求的文档啦。
先把你给出的示例集合数据贴出来,方便咱们对照:
[ { "_id": 1, "RoomFrom": 100, "RoomTo": 200, "PoolFrom": 150, "PoolTo": 155, "FloorFrom": 170, "FloorTo": 180 }, { "_id": 2, "RoomFrom": 150, "RoomTo": 300, "PoolFrom": 170, "PoolTo": 200, "FloorFrom": 170, "FloorTo": 180 }, { "_id": 3, "RoomFrom": 210, "RoomTo": 230, "PoolFrom": 100, "PoolTo": 110, "FloorFrom": 500, "FloorTo": 505 }, { "_id": 4, "RoomFrom": 300, "RoomTo": 350, "PoolFrom": 400, "PoolTo": 450, "FloorFrom": 600, "FloorTo": 650 }, { "_id": 5, "RoomFrom": 400, "RoomTo": 401, "PoolFrom": 500, "PoolTo": 503, "FloorFrom": 700, "FloorTo": 711 } ]
场景1:所有字段范围都要与目标范围存在交集
假设你的Range variant #1是这样的(补全你未写完的内容方便演示):
- Room范围:
RoomFrom=140, RoomTo=220 - Pool范围:
PoolFrom=140, PoolTo=190 - Floor范围:
FloorFrom=160, FloorTo=190
那对应的MongoDB查询语句就是:
db.yourCollectionName.find({ $and: [ // Room范围交集判断 { RoomFrom: { $lte: 220 } }, { RoomTo: { $gte: 140 } }, // Pool范围交集判断 { PoolFrom: { $lte: 190 } }, { PoolTo: { $gte: 140 } }, // Floor范围交集判断 { FloorFrom: { $lte: 190 } }, { FloorTo: { $gte: 160 } } ] })
运行这个查询后,你会得到_id=1和_id=2的文档:
- _id=1:三个字段的范围都和目标范围存在交集
- _id=2:三个字段的范围也都满足交集条件
- _id=3及以后的文档:至少有一个字段范围和目标范围无重叠,会被排除
场景2:任意一个字段范围与目标范围存在交集即可
如果你需要的是只要Room、Pool、Floor其中任意一个范围和目标范围有交集就筛选出来,那把$and换成$or,同时给每个字段组的判断加上嵌套$and即可:
db.yourCollectionName.find({ $or: [ // Room范围交集 { $and: [{ RoomFrom: { $lte: 220 } }, { RoomTo: { $gte: 140 } }] }, // Pool范围交集 { $and: [{ PoolFrom: { $lte: 190 } }, { PoolTo: { $gte: 140 } }] }, // Floor范围交集 { $and: [{ FloorFrom: { $lte: 190 } }, { FloorTo: { $gte: 160 } }] } ] })
这个查询会返回_id=1、2、3:因为_id=3的Room范围210-230和目标Room范围140-220存在交集,所以会被选中。
关键逻辑再强调
不管是哪个字段组,只要集合里的XFrom小于等于目标的XTo,同时目标的XFrom小于等于集合里的XTo,这两个区间就一定存在重叠部分。比如:
- [100,200] 和 [140,220]:
100<=220且140<=200→ 有交集 - [170,200] 和 [140,190]:
170<=190且140<=200→ 有交集 - [100,110] 和 [140,190]:
100<=190但140>110→ 无交集
只要掌握这个逻辑,不管你后续调整目标范围还是字段,都能快速写出对应的查询语句。
备注:内容来源于stack exchange,提问作者Valentin Borisenko
相关产品推荐
相关产品推荐

