Suppose we have a mongodb collection with 6 columns:
- RoomFrom
- RoomTo
- PoolFrom
- PoolTo
- FloorFrom
- FloorTo
Now I would like to select rows where range *From / *To intersect with another ranges.
I will give an example of collections that can be.
Collection #1:
[
{
_id: 1,
RoomFrom: 100,
RoomTo: 200,
PoolFrom: 150,
PoolTo: 160,
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: 430,
PoolFrom: 500,
PoolTo: 530,
FloorFrom: 700,
FloorTo: 711
}
]
Collection #2:
[
{
_id: 1,
RoomFrom: 100,
PoolFrom: 150,
PoolTo: 180,
FloorFrom: 170,
FloorTo: 180
},
{
_id: 2,
RoomFrom: 150,
RoomTo: 300,
PoolFrom: 170,
FloorFrom: 170,
FloorTo: 180
},
{
_id: 3,
RoomFrom: 210,
RoomTo: 230,
PoolFrom: 100,
PoolTo: 290,
FloorFrom: 500,
},
{
_id: 4,
RoomFrom: 300,
PoolFrom: 170,
FloorFrom: 600,
},
{
_id: 5,
RoomFrom: 400,
RoomTo: 401,
PoolFrom: 350,
PoolTo: 470,
FloorFrom: 700,
FloorTo: 711
}
]
Collection #3:
[
{
_id: 1,
RoomFrom: 100,
PoolFrom: 150,
PoolTo: 180,
FloorFrom: 170,
FloorTo: 180
},
{
_id: 2,
RoomFrom: 150,
RoomTo: 300,
PoolFrom: 200,
FloorFrom: 170,
FloorTo: 180
},
{
_id: 3,
RoomFrom: 210,
RoomTo: 230,
PoolFrom: 100,
PoolTo: 130,
FloorFrom: 500,
},
{
_id: 4,
RoomFrom: 300,
PoolFrom: 300,
FloorFrom: 600,
},
{
_id: 5,
RoomFrom: 400,
RoomTo: 401,
PoolFrom: 270,
PoolTo: 300,
FloorFrom: 700,
FloorTo: 711
}
]
Now we have the ranges like this:
<- Input-Range ->
โโโโโโโโโโโโ|โโโโโโโโโโโโโโโโ|โโโโโโโโโโโโ Intersects
Range 1: |โโโโโ| No
Range 2: |โโโโโ| Yes
Range 3: |โโโโโ| Yes
Range 4: |โโโโโ| Yes
Range 5: |โโโโโ| No
Range 6: |โโโโโโโโโโโโโโโโโโโโโโ| Yes
Now letโs look at the filtering options.
RoomFrom[To]: Filter input range from = 350, to = 550. Now letโs look at the collections.
Collection #1:
350 <-Input-Range -> 550
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโ Intersects
Object #1:|โโโโโโโโโโ| No
Object #2: |โโโโโโโโโโโโโโโ| No
Object #3: |โโ| No
Object #4: |โโโโ| Yes
Object #5: |โโโ| Yes
As a result of the query we should receive the following objects: #4, #5.
Collection #2:
350 <-Input-Range -> 550
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโ Intersects
Object #1:|---------------------------------------------------------- Yes
Object #2: |----------------------------------------------------- Yes
Object #3: |โโ| No
Object #4: |-------------------------------------- Yes
Object #5: |---------------------------- Yes
As a result of the query we should receive the following objects: #1, #2, #4, #5.
Collection #3:
350 <-Input-Range -> 550
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโ Intersects
Object #1:|---------------------------------------------------------- Yes
Object #2: |โโโโโโโโโโโโโโโ| No
Object #3: |โโ| No
Object #4: |-------------------------------------- Yes
Object #5: |โโโ| Yes
As a result of the query we should receive the following objects: #1, #4, #5.
Now letโs complicate the filter and add one more parameter. Let me clarify that the sequence of filters is important. First comes the filter with the range RoomFrom[To], and after it comes the filter - PoolFrom[To].
- RoomFrom[To]: Filter input range from = 350, to = 550.
- PoolFrom[To]: Filter input range from = 50, to = 250.
Now letโs look at the collections.
Collection #1:
350 <-Input-Range -> 550 RoomFrom[To]
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโ Intersects
Object #1:|โโโโโโโโโโ| No
Object #2: |โโโโโโโโโโโโโโโ| No
Object #3: |โโ| No
Object #4: |โโโโ| Yes
Object #5: |โโโ| Yes
50 <-Input-Range -> 250 PoolFrom[To]
โโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Intersects
Object #1: |โ| Yes
Object #2: |โโโ| Yes
Object #3:|โ| Yes
Object #4: |โโโโโ| No
Object #5: |โโโ| No
The query should return no objects.
Collection #2:
350 <-Input-Range -> 550
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโ Intersects
Object #1:|---------------------------------------------------------- Yes
Object #2: |----------------------------------------------------- Yes
Object #3: |โโ| No
Object #4: |-------------------------------------- Yes
Object #5: |---------------------------- Yes
50 <-Input-Range -> 250 PoolFrom[To]
โโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Intersects
Object #1: |โโโ| Yes
Object #2: |--------------------------------------------------- Yes
Object #3:|โโโโโโโโโโโโโโโโโโโ| Yes
Object #4: |--------------------------------------------------- Yes
Object #5: |โโโโโโโโโโโโ| No
As a result of the query we should receive the following objects: #1, #2, #4.
Collection #3:
350 <-Input-Range -> 550
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโ Intersects
Object #1:|---------------------------------------------------------- Yes
Object #2: |----------------------------------------------------- Yes
Object #3: |โโ| No
Object #4: |-------------------------------------- Yes
Object #5: |---------------------------- Yes
50 <-Input-Range -> 250 PoolFrom[To]
โโโโโ|โโโโโโโโโโโโโโโโโโโโ|โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Intersects
Object #1: |โโโ| Yes
Object #2: |----------------------------------------------- Yes
Object #3:|โโโ| Yes
Object #4: |-------------------------------------- No
Object #5: |โโโ| No
As a result of the query we should receive the following objects: #1, #2.
If we add another filter FloorFrom[To], then the existing result should also be filtered - like the previous 2 examples.
As a result, we should get a universal query that will take into account the following:
- only the filter value can be filled in -
from
- both filter values โโare filled -
from
andto
- only the filter value can be filled in -
to
User @ray (thanks a lot for this) gave a great working example, which only works for the filtering condition:
- both filter values โโare filled -
from
andto
It remains to change the current query so that it takes into account the remaining 2 conditions:
- only the filter value can be filled in -
from
- only the filter value can be filled in -
to
It is also worth considering in the query that the objects may not be completely filled in.
Thanks.