'Query MongoDB where at least one value of an array is inside a range
How might I query MongoDB for all documents where at least one value in an array falls inside a range, e.g. 8 to 10.
If I query it as an enumeration, this works as desired: {x : {$in: [8, 9, 10]}} . This will return all records where any value in x is in the set [8,9,10]. In the example below it returns the first record but not the second.
But in my application, I can't enumerate the set as the range could be potentially very large and not necessarily even integers.
My first guess was { x: {$gte: 8, $lte: 10}} but this fails, as a document might have at least one value above the lower bound, and at least one value below the upper bound, and would thus pass even though no value is both above the lower and below the upper.
In the example below, both records are returned, even though record 2 has no values in 8–10:
[
{
"key": 1,
"x": [ 5,9,10 ]
},
{
"key": 2,
"x": [ 2, 3, 7, 999 ]
}
]
Example on MongoPlayground: https://mongoplayground.net/p/2ZLfTcGnW4g
Solution 1:[1]
You can use an aggregation pipeline to $filter only matching items as a condition to match the document:
db.collection.aggregate([
{
$addFields: {
valid: {
$size: {
$filter: {
input: "$x",
as: "item",
cond: {$and: [{$gte: ["$$item", rangeMin]}, {$lte: ["$$item", rangeMax]}]}
}
}
}
}
},
{
$match: {valid: {$gt: 0}}
},
{
$unset: "valid"
}
])
Solution 2:[2]
As others have mentioned there are no private methods in Python. I also don't know how to make it invisible for intelisense (probably there is some setting), but what you could theoretically do is this:
import re
def make_private(func):
def inner(*args, **kwargs):
name = func.__name__
pattern = re.compile(fr'(.*)\.{name}')
with open(__file__) as file:
for line in file:
lst = pattern.findall(line)
if (lst and not line.strip().startswith('#')
and not all(g.strip() == 'self' for g in lst)):
raise Exception()
return func(*args, **kwargs)
return inner
class MyClass:
@make_private
def some_method(self):
pass
def some_other_method(self):
self.some_method()
m = MyClass()
# m.some_method()
m.some_other_method()
It (make_private) is a decorator which basically when you call the function it is decorating, it first reads the entire file line by line and tries to find if in all of the file this method is called without being prefixed with self.. So if it is not then it is considered to be called from outside the class and an Exception is raised (probably add some message to it tho).
Issues could start once you have multiple files and this wouldn't entirely prevent someone from calling it if they really wanted for example if they did it like this:
self = MyClass()
self.some_method()
But mostly this would raise an exception.
Solution 3:[3]
OK Solved, to hide the method to the ide's Intellisense i added the double underscore (works fine with pycharm, not with vscode) then i used the accessify module to prevent forced execution calling myobj._myclass__somemethod()
from accessify import private
class myclass:
@private
def __somemethod(self)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | nimrod serok |
| Solution 2 | Matiiss |
| Solution 3 | Alexandro |
