Вопрос или проблема
Пересечение диапазона нескольких значений строк
Предположим, у нас есть коллекция mongodb с 6 столбцами:
- RoomFrom
- RoomTo
- PoolFrom
- PoolTo
- FloorFrom
- FloorTo
Теперь я хотел бы выбрать строки, где диапазоны *From / *To пересекаются с другими диапазонами.
Например:
- Объект №1
- RoomFrom = 100
- RoomTo = 200
- PoolFrom = 150
- PoolTo = 155
- FloorFrom = 170
- FloorTo = 180
- Объект №2
- RoomFrom = 150
- RoomTo = 300
- PoolFrom = 170
- PoolTo = 200
- FloorFrom = 100
- FloorTo = 200
- Объект №3
- RoomFrom = 210
- RoomTo = 230
- PoolFrom = 100
- PoolTo = 110
- FloorFrom = 500
- FloorTo = 505
- Объект №4
- RoomFrom = 300
- RoomTo = 350
- PoolFrom = 400
- PoolTo = 450
- FloorFrom = 600
- FloorTo = 650
- Объект №5:
- RoomFrom = 400
- RoomTo = 401
- PoolFrom = 500
- PoolTo = 503
- FloorFrom = 700
- FloorTo = 711
Теперь у нас есть диапазоны:
Вариант №1
- RoomFrom = 205
- RoomTo = 350
Таким образом, в этом диапазоне у меня есть объекты в результатах:
- Объект №2
- Объект №3
- Объект №4
Какой запрос в этом случае с “find”?
У меня есть хорошие примеры от Yong Shun (большое спасибо!!!):
- https://mongoplayground.net/p/Hx6XZwMvbb7
- https://mongoplayground.net/p/0vmG5yQbzyV
- https://mongoplayground.net/p/-5LcMtHxIn7
- https://mongoplayground.net/p/hd6Sz1iL1Zx
Но это только для одного случая …
Вариант №2
- RoomFrom = 205
- RoomTo = 350
- PoolFrom = 110
- PoolTo = 180
Таким образом, в этом диапазоне у меня есть объекты в результатах:
- Объект №2
- Объект №3
Какой запрос в этом случае с “find”?
Вариант №3
- RoomFrom = 205
- RoomTo = 350
- PoolFrom = 110
- PoolTo = 180
- FloorFrom = 150
- FloorTo = 300
Таким образом, в этом диапазоне у меня есть объекты в результатах:
- Объект №2
Какой запрос в этом случае с “find”?
Этот https://mongoplayground.net/p/LDvAlyERpXD работает хорошо, но только для одной пары RoomFrom / RoomTo.
Таким образом, мне нужны запросы, когда есть диапазоны для каждой пары:
- от
- от + до
- до
Спасибо.
Ответ или решение
Для решения задачи интерсекции диапазонов в MongoDB мы можем воспользоваться механизмом запроса с использованием оператора $and
и создания условий для каждого диапазона. Давайте рассмотрим каждый из предложенных вариантов и составим соответствующие запросы.
Вариант #1
Диапазоны:
- RoomFrom = 205
- RoomTo = 350
Запрос:
db.collection.find({
$and: [
{ RoomFrom: { $lt: 350 } },
{ RoomTo: { $gt: 205 } }
]
})
В данном случае мы ищем объекты, у которых:
- RoomFrom меньше верхней границы диапазона (350)
- RoomTo больше нижней границы диапазона (205)
Вариант #2
Диапазоны:
- RoomFrom = 205
- RoomTo = 350
- PoolFrom = 110
- PoolTo = 180
Запрос:
db.collection.find({
$and: [
{ RoomFrom: { $lt: 350 } },
{ RoomTo: { $gt: 205 } },
{ PoolFrom: { $lt: 180 } },
{ PoolTo: { $gt: 110 } }
]
})
Здесь добавляются условия для пулов; мы проверяем, чтобы верхний предел пулов был меньше 180, а нижний — больше 110.
Вариант #3
Диапазоны:
- RoomFrom = 205
- RoomTo = 350
- PoolFrom = 110
- PoolTo = 180
- FloorFrom = 150
- FloorTo = 300
Запрос:
db.collection.find({
$and: [
{ RoomFrom: { $lt: 350 } },
{ RoomTo: { $gt: 205 } },
{ PoolFrom: { $lt: 180 } },
{ PoolTo: { $gt: 110 } },
{ FloorFrom: { $lt: 300 } },
{ FloorTo: { $gt: 150 } }
]
})
Этот запрос включает все диапазоны, которые мы хотели бы проверить, условием является то, что каждый «From» должен быть меньше верхнего предела соответствующего диапазона и, соответственно, каждый «To» должен быть больше нижнего предела.
Объяснение логики запроса
Логика, используемая в этих запросах, заключается в том, что диапазоны пересечений можно определить, проверяя условия на насыщение. Например, о пересечении двух диапазонов (от A до B и от C до D) можно судить по следующим критериям:
- A должно быть меньше D, чтобы начать отсчет от нижней границы второго диапазона.
- B должно быть больше C, чтобы не выйти за верхнюю границу первого диапазона.
Каждое условие в запросе проверяет эти критерии для соответствующих полей. В результате мы получаем объекты, которые соответствуют всем заданным диапазонам.
Заключение
С помощью вышеуказанных запросов вы можете получать данные из MongoDB, удовлетворяющие условиям пересечения диапазонов для различных категорий. При необходимости вы можете добавлять дополнительные поля или изменять диапазоны в соответствии с вашими выборками.