mongoquery icon indicating copy to clipboard operation
mongoquery copied to clipboard

A python implementation of mongodb queries

========== mongoquery

.. image:: https://travis-ci.org/kapouille/mongoquery.svg?branch=master :target: https://travis-ci.org/kapouille/mongoquery

A utility library that provides a MongoDB <http://www.mongodb.org>_-like query language for querying python collections. It's mainly intended to parse objects structured as fundamental types in a similar fashion to what is produced by JSON or YAML parsers. It follows the specification of queries for MongoDB version 3.4.


Usage

Example:

.. code-block:: python

from mongoquery import Query, QueryError

records = [
    {"a": 5, "b": 5, "c": None},
    {"a": 3, "b": None, "c": 8},
    {"a": None, "b": 3, "c": 9},
    {"a": 1, "b": 2, "c": 3},
    {"a": 2, "c": 5},
    {"a": 3, "b": 2},
    {"a": 4},
    {"b": 2, "c": 4},
    {"b": 2},
    {"c": 6}
]

a_is_3 = Query({"a": 3})

# match a single object
matched = a_is_3.match(records[1])
assert matched

matched = a_is_3.match(records[0])
assert not matched

# filter elements
filtered = filter(
    a_is_3.match,
    records
)
assert filtered == [records[1], records[5]]

# incorrect filters raise QueryError
try:
    matched = query({"$foo": 2}).match(records[1])
except QueryError:
    pass  # => "$foo" operator isn't supported

Query syntax

The syntax of queries matches closely the one of MongoDB queries <http://docs.mongodb.org/manual/tutorial/query-documents/>_, and translates it to python using the following rules:

  • operators and field identifiers are expressed as strings. For instance, the following MongoDB query:

    .. code-block:: javascript

    { memos: { $elemMatch: { memo: 'on time', by: 'billing' } } }

    Translates straightforwardly to the following Python dict:

    .. code-block:: python

    { "memos": { "$elemMatch": { "memo": 'on time', "by": 'billing' } } }

  • regular expressions are expected to be expressed as string containing the MongoDB regular expression syntax. For instance:

    .. code-block:: javascript

    {description: {$regex: /^S/m}}

    Translates to the following Python dict:

    .. code-block:: python

    {"description": {"$regex": "/^S/m"}}

  • the boolean, null syntax used in MongoDB follows the JavaScript syntax. It is expected the python equivalents are used. For instance:

    .. code-block:: javascript

    {a: {$exists: true}, b: null}

    Translates to the following Python dict:

    .. code-block:: python

    {"a": {"$exists": True}, "b": None}


Functional differences with MongoDB's queries

There are a few features that are not supported by mongoquery: - Only the "/pattern/<options>" syntax is supported for $regex. As a consequence, $options isn't supported. Alternatively you can compile a regex using re.compile and supply options as parameters, and pass the re.Pattern object as the value of $regex. - $text hasn't been implemented. - Due to the pure python nature of this library, $where isn't supported. - The Geospatial operators $geoIntersects, $geoWithin, $nearSphere, and $near are not implemented. - Projection operators `$, $elemMatch, $meta, and $sliceare not implemented (only querying is implemented) -$type`` is limited to recognising generic python types, it won't look into recognising the format of the data (for instance, it doesn't check Object ID's format, only that they are strings)