This post is a continuation of the previous posts:
- Intersection of the range of values
- MongoDB – Intersection of the range of multiple row values
- MongoDB: Intersection of the range of multiple row values with object fields
Suppose we have a mongodb collection with 6 columns in object field:
- investmentParameters.capitalAppreciationFrom
- investmentParameters.capitalAppreciationTo
- investmentParameters.rentalYieldFrom
- investmentParameters.rentalYieldTo
- investmentParameters.occupancyRateFrom
- investmentParameters.occupancyRateTo
Now I would like to select rows where range** *From / *To intersect with another ranges.
For example:
[
{
_id: 1,
"investmentParameters": {
"capitalAppreciationFrom": 30,
"capitalAppreciationTo": 60,
"rentalYieldFrom": 30,
"rentalYieldTo": 60,
"occupancyRateFrom": 30,
"occupancyRateTo": 60
}
},
{
_id: 2,
"investmentParameters": {
"capitalAppreciationFrom": 17,
"capitalAppreciationTo": 80,
"rentalYieldFrom": 17,
"rentalYieldTo": 80,
"occupancyRateFrom": 17,
"occupancyRateTo": 80
}
},
{
_id: 3,
"investmentParameters": {
"capitalAppreciationFrom": 27,
"capitalAppreciationTo": 87,
"rentalYieldFrom": 27,
"rentalYieldTo": 87,
"occupancyRateFrom": 27,
"occupancyRateTo": 87
}
},
{
_id: 4,
"investmentParameters": {
"capitalAppreciationFrom": 23,
"capitalAppreciationTo": 57,
"rentalYieldFrom": 23,
"rentalYieldTo": 57,
"occupancyRateFrom": 23,
"occupancyRateTo": 57
}
}
]
** – range in this case is:
- value – from
- values – from and to
- value – to
So lets call our filter fields like this:
- capitalAppreciationFilter which can be:
- capitalAppreciationFilterFrom
- capitalAppreciationFilterFrom + capitalAppreciationFilterTo
- capitalAppreciationFilterTo
- rentalYieldFilter which can be:
- rentalYieldFilterFrom
- rentalYieldFilterFrom + rentalYieldFilterTo
- rentalYieldFilterTo
- occupancyRateFilter which can be:
- occupancyRateFilterFrom
- occupancyRateFilterFrom + occupancyRateFilterTo
- occupancyRateFilterTo
If we talk about fields in the DB, then we have the following correspondences with the filter:
- investmentParameters.capitalAppreciationFrom – capitalAppreciationFilterFrom
- investmentParameters.capitalAppreciationTo – capitalAppreciationFilterTo
- investmentParameters.rentalYieldFrom – rentalYieldFilterFrom
- investmentParameters.rentalYieldTo – rentalYieldFilterTo
- investmentParameters.occupancyRateFrom – occupancyRateFilterFrom
- investmentParameters.occupancyRateTo – occupancyRateFilterTo
We need to write queries that will select the intersections of ranges (not the range occurrences, but the intersection).
For example we take Object #1 and Condition #1:
occupancyRateFilterFrom - $gte: 30
rentalYieldFilterFrom - $gte: 20
rentalYieldFilterTo - $lte: 40
First range with from
value – occupancyRateFilterFrom = $gte: 30
falls within the range of 30 to 60 (investmentParameters.capitalAppreciationFrom = 30
and investmentParameters.capitalAppreciationTo = 60
). Next range with from
+ to
values – rentalYieldFilterFrom = $gte: 20
/ rentalYieldFilterTo = $lte: 40
intersects (is included in the range investmentParameters.rentalYieldFrom = 30
and investmentParameters.rentalYieldTo = 60
) with the range from 30 to 60. Thus, the Object #1 gets into the selection. The same thing with the other objects – all get into the selection under current query conditions.
Also, if it may be important:
/# mongo --version
MongoDB version v3.2.11
We need to write queries that will select the intersections of ranges (not the range occurrences, but the intersection).
For example I will give you the conditions under which 4 objects should always be selected.
Condition #1
occupancyRateFilterFrom - $gte: 30
rentalYieldFilterFrom - $gte: 20
rentalYieldFilterTo - $lte: 40
Condition #2
occupancyRateFilterFrom - $gte: 27
rentalYieldFilterFrom - $gte: 20
rentalYieldFilterTo - $lte: 40
Condition #3
occupancyRateFilterFrom - $gte: 37
rentalYieldFilterFrom - $gte: 20
rentalYieldFilterTo - $lte: 40
Condition #4
occupancyRateFilterFrom - $gte: 40
rentalYieldFilterFrom - $gte: 20
rentalYieldFilterTo - $lte: 40
Under all these 4 conditions, 4 objects must always be selected.
Now I change occupancyRateFilterFrom - $lte: 16
so we have the condition:
occupancyRateFilterTo - $gte: 16
rentalYieldFilterFrom - $gte: 20
rentalYieldFilterTo - $lte: 40
then none of the 4 objects should be included in the query result.
Next we have the condition:
capitalAppreciationFilterFrom - $gte: 62
occupancyRateFilterFrom - $gte: 16
rentalYieldFilterFrom - $gte: 20
rentalYieldFilterTo - $lte: 40
As a result of the selection, we should see the following objects:
- Object #2
- Object #3
And of course, the sampling conditions can be combined:
occupancyRateFilterFrom - $gte: x
rentalYieldFilterFrom - $gte: x
rentalYieldFilterTo - $lte: x
occupancyRateFilterFrom - $gte: x
occupancyRateFilterTo - $lte: x
rentalYieldFilterFrom - $gte: x
rentalYieldFilterTo - $lte: x
capitalAppreciationFilterFrom - $gte: x
occupancyRateFilterFrom - $gte: x
occupancyRateFilterTo - $lte: x
rentalYieldFilterFrom - $gte: x
rentalYieldFilterTo - $lte: x
capitalAppreciationFilterFrom - $gte: x
capitalAppreciationFilterTo - $gte: x
occupancyRateFilterFrom - $gte: x
occupancyRateFilterTo - $lte: x
rentalYieldFilterFrom - $gte: x
rentalYieldFilterTo - $lte: x
capitalAppreciationFilterFrom - $gte: x
capitalAppreciationFilterTo - $gte: x
and so on …
Each subsequent filter reduces the current selection, thereby narrowing the selection result.
2
Answers
Maybe this will be useful for someone. At the moment I have such solutions.
Filter - From: capitalAppreciationFromFilter = 100
Example.
Filter - From / To: capitalAppreciationFromFilter = 100 / capitalAppreciationToFilter = 300
Example.
Filter - To: capitalAppreciationToFilter = 300
Example.
This is not a valid answer, however it may help you to formalize a better question and enables other people to give you a solution.
Maybe as a starting point, you should make a small drawing to visualize your condition of intersecting ranges. Could be like this:
Or for a single value, it could be
Then it is easier to compose the condition by code.
You mention these three cases:
You explained the first and second one, but nobody has a clue what "value – to" means.
Why does a
occupancyRate
filter has an effect on anycapitalAppreciation
range?Why do you expect all 4 documents should be selected? Document #1 is
{ occupancyRateFrom: 30, occupancyRateTo: 60 }
does not fall into 27, thus Condition #2 should not select document #1.Why?
Document #2 has
{ occupancyRateFrom: 17, occupancyRateTo: 80}
and document #3 has{ occupancyRateFrom: 27, occupancyRateTo: 87}
which both do not fall into 16.Note, I am not going to start again a discussion with comments. Take this answer, review your requirements, ask a new proper question with valid and consistent input data, expected result and what you have tried. Otherwise leave it!