GithubHelp home page GithubHelp logo

mongoquery's People

Contributors

ch3pjw avatar dgs3 avatar florianludwig avatar foolswood avatar itay avatar kapouille avatar kerfab avatar opichals avatar pareyesv avatar tacaswell avatar tema-pg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mongoquery's Issues

'$exists' does not work with JSON paths

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.

$in behavior not working as expected

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?

Tagging Releases on Github

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!

$exists doesn't seem to work correctly for nested objects

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

match raises TypeError with elemMatch if field matched does not exist

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

Checks against strings don't work properly

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:

  1. Check against explicit types instead of Sequence
  2. Ensure that it is not a string-like type (e.g. bytes, unicode, str, etc)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.