kapouille / mongoquery Goto Github PK
View Code? Open in Web Editor NEWA python implementation of mongodb queries
License: The Unlicense
A python implementation of mongodb queries
License: The Unlicense
Given the following object:
o = { 'a' : { 'b' : { 'c' : True } } }
The query:
q = Query({ 'a.b' : { '$exists' : True } })
Will result in:
q.match(o)
False
But it works when specifying nested objects rather than a path:
q = Query({'a' : { 'b' : {'$exists' : True}}})
q.match(o)
True
This seems to be due to specific handling and conditions within the package on '$exists'. A fix would be most welcomed! Thank you for that useful library.
Hello everyone,
I encountered an issue while working with $in
, it is not working as expected (the way MongoDB does work).
The following should have returned True
instead of False
:
>>> from mongoquery import Query
>>> o = {'a': {'b': ['test1', 'test2']}}
>>> q = Query({'a.b': {'$in': ['test2']}})
>>> q.match(o)
False
Would it be okay to update mongoquery so that $in
/$nin
follow MongoDB's specifications?
Hi,
I am package maintainer of mongoquery in Fedora (python-mongoquery). I see there are new versions of mongoquery on PyPi, but they are not tagged on github.
Will it be possible to tag new versions also here?
Thanks!
Looks like the current implementation fails for the following:
import mongoquery
q = mongoquery.Query({"obj.id": {"$exists": True, "$regex": "no match"}})
assert q.match({"obj": {"id": "some-id"}}) == False
with
Traceback (most recent call last):
File "/tmp/mq/mq.py", line 5, in <module>
assert q.match({"obj": {"id": "some-id"}}) == False
AssertionError
Actual Behaviour
Using ElemMatch operator against a field which isn't iterable raises TypeError
Haven't verified, but probably happens with other operators that are natural to use with arrays
Desired Behaviour
Return no match
Perhaps QueryError would be suitable, since ElemMatch shouldn't be used against fields that aren't iterable. But I think the convention is not to have any expectations about the types of the fields
Glad to make a PR here if maintainer can advise what the behavior should be
Minimal working example
from mongoquery import Query, QueryError
record = {}
subscription = Query({
"ratios": {
"$elemMatch": {
"$gte": {
"confidence": 0.5
}
}
}
})
Traceback
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-630f64a0db6f> in <module>()
----> 1 subscription.match(record)
/home/joth/projects/mongoquery-speed/venv/lib/python2.7/site-packages/mongoquery/__init__.pyc in match(self, entry)
25
26 def match(self, entry):
---> 27 return self._match(self._definition, entry)
28
29 def _match(self, condition, entry):
/home/joth/projects/mongoquery-speed/venv/lib/python2.7/site-packages/mongoquery/__init__.pyc in _match(self, condition, entry)
31 return all(
32 self._process_condition(sub_operator, sub_condition, entry)
---> 33 for sub_operator, sub_condition in condition.items()
34 )
35 else:
/home/joth/projects/mongoquery-speed/venv/lib/python2.7/site-packages/mongoquery/__init__.pyc in <genexpr>((sub_operator, sub_condition))
31 return all(
32 self._process_condition(sub_operator, sub_condition, entry)
---> 33 for sub_operator, sub_condition in condition.items()
34 )
35 else:
/home/joth/projects/mongoquery-speed/venv/lib/python2.7/site-packages/mongoquery/__init__.pyc in _process_condition(self, operator, condition, entry)
98 return False
99 extracted_data = entry[operator]
--> 100 return self._match(condition, extracted_data)
101
102 ##################
/home/joth/projects/mongoquery-speed/venv/lib/python2.7/site-packages/mongoquery/__init__.pyc in _match(self, condition, entry)
31 return all(
32 self._process_condition(sub_operator, sub_condition, entry)
---> 33 for sub_operator, sub_condition in condition.items()
34 )
35 else:
/home/joth/projects/mongoquery-speed/venv/lib/python2.7/site-packages/mongoquery/__init__.pyc in <genexpr>((sub_operator, sub_condition))
31 return all(
32 self._process_condition(sub_operator, sub_condition, entry)
---> 33 for sub_operator, sub_condition in condition.items()
34 )
35 else:
/home/joth/projects/mongoquery-speed/venv/lib/python2.7/site-packages/mongoquery/__init__.pyc in _process_condition(self, operator, condition, entry)
88 if operator.startswith("$"):
89 try:
---> 90 return getattr(self, "_" + operator[1:])(condition, entry)
91 except AttributeError:
92 raise QueryError(
/home/joth/projects/mongoquery-speed/venv/lib/python2.7/site-packages/mongoquery/__init__.pyc in _elemMatch(self, condition, entry)
293 for sub_operator, sub_condition in condition.items()
294 )
--> 295 for element in entry
296 )
297
TypeError: '_Undefined' object is not iterable
See the following case:
>>> import mongoquery
>>> a = {"a": "5", "b": 6}
>>> query = mongoquery.Query({"a": 2})
>>> query.match(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/mongoquery/__init__.py", line 23, in match
return self._match(self._definition, entry)
File "/usr/local/lib/python2.7/site-packages/mongoquery/__init__.py", line 29, in _match
for sub_operator, sub_condition in condition.items()
File "/usr/local/lib/python2.7/site-packages/mongoquery/__init__.py", line 29, in <genexpr>
for sub_operator, sub_condition in condition.items()
File "/usr/local/lib/python2.7/site-packages/mongoquery/__init__.py", line 72, in _process_condition
return self._match(condition, extracted_data)
File "/usr/local/lib/python2.7/site-packages/mongoquery/__init__.py", line 33, in _match
return condition in entry
TypeError: 'in <string>' requires string as left operand, not int
This happens because we have:
def _match(self, condition, entry):
if isinstance(condition, Mapping):
return all(
self._process_condition(sub_operator, sub_condition, entry)
for sub_operator, sub_condition in condition.items()
)
else:
if isinstance(entry, Sequence): <----- HERE
return condition in entry
else:
return condition == entry
str
is actually a subtype of collections.Sequence
, and thus we try and do an "in" comparison, when we really want equality. This seems like a bug even if you had two strings, because this can happen:
>>> b = {"a": "567", "b": 6}
>>> query2 = mongoquery.Query({"a": "6"})
>>> query2.match(b)
True
Same reason - we're doing an in
when you want to do a strict equality check. There are a couple of possible fixes:
Sequence
https://bugzilla.redhat.com/show_bug.cgi?id=1792973
mongoquery/mongoquery/__init__.py
Line 7 in 2629074
Thanks for the library!
The latest version on conda-forge is 1.3.5. Can you update to a more recent version? At least 1.3.6 is listed in requirements for apstools, part of bluesky.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.