假设我们有一个包含 6 列的 mongodb 集合:
现在我想选择范围*From / *与另一个范围相交的行。
例如:
[
{
_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
所以在这个范围内我的结果中有对象:
本例中“find”的查询是什么?
我有来自Yong Shun的很好的例子(非常感谢!!!):
但这只是针对一种情况...
范围变体#2
所以在这个范围内我的结果中有对象:
本例中“find”的查询是什么?
范围变体#3
所以在这个范围内我的结果中有对象:
本例中“find”的查询是什么?
这个 https://mongoplayground.net/p/LDvAlyERpXD 工作正常,但仅适用于一对 RoomFrom / RoomTo,这个适用于 3 对:https://mongoplayground.net/p/81MKW9AkelA。
所以我需要查询每对的范围:
谢谢。
使用这篇文章中的区间交集算法,我们可以看到,当任一区间的起点大于另一个区间的终点时,2 个交集不会重叠。我们可以使用
$not
来检查相反的情况,即发生重叠的情况。
在 MongoDB 中,这将类似于以下表达式:
{
$not: {
"$or": [
{
$gt: [
"$$roomFromInput",
"$RoomTo"
]
},
{
$gt: [
"$RoomFrom",
"$$roomToInput"
]
}
]
}
}
剩下的工作只是对游泳池和地板重复它,我们可以使用
$and
将它们链接起来。在这里,我使用 $let
来组织变量。
db.collection.aggregate([
{
"$match": {
$expr: {
$let: {
vars: {
roomFromInput: 201,
roomToInput: 350,
poolFromInput: 100,
poolToInput: 350,
floorFromInput: 180,
floorToInput: 185
},
in: {
$and: [
//room
{
$not: {
"$or": [
{
$gt: [
"$$roomFromInput",
"$RoomTo"
]
},
{
$gt: [
"$RoomFrom",
"$$roomToInput"
]
}
]
}
},
//pool
{
$not: {
"$or": [
{
$gt: [
"$$poolFromInput",
"$PoolTo"
]
},
{
$gt: [
"$PoolFrom",
"$$poolToInput"
]
}
]
}
},
//floor
{
$not: {
"$or": [
{
$gt: [
"$$floorFromInput",
"$FloorTo"
]
},
{
$gt: [
"$FloorFrom",
"$$floorToInput"
]
}
]
}
}
]
}
}
}
}
}
])
注: