Skip to content

Instantly share code, notes, and snippets.

@amcgregor
Last active April 5, 2019 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amcgregor/6ddbda735e6ded267d31 to your computer and use it in GitHub Desktop.
Save amcgregor/6ddbda735e6ded267d31 to your computer and use it in GitHub Desktop.
A comparison between marrow.mongo query structuring results and other ODMs.
from marrow.mongo import Document, F
from marrow.mongo.field import Array, Number, String
# 2016? Yikes! Hello from 2019! Imports updated, missing REPRs added.
class Person(Document):
name = String()
age = Number()
tag = Array(String())
Person.name == "Alice"
# Op({'name': 'Alice'})
Person.age >= 21
# Op({'age': {'$gte': 21}})
query = (Person.name == "Alice") & (Person.age >= 21) & Person.tag.any(["foo", "bar"])
# query = Ops({'name': 'Alice', 'tag': {'$in': ['foo', 'bar']}, 'age': {'$gte': 21}})
query = a.as_query # We now have the above MongoDB query by itself.
# query = {'name': 'Alice', 'tag': {'$in': ['foo', 'bar']}, 'age': {'$gte': 21}}
Ops(query) & (Document.age < 65) # And can re-bundle and update it!
# Ops({'name': 'Alice', 'tag': {'$in': ['foo', 'bar']}, 'age': {'$gte': 21, '$lt': 65}})
query = (Person.name == "Alice") & (Person.age >= 21) | Person.tag.any(["foo", "bar"])
# query = Filter([('$or', [
# {'name': 'Alice', 'age': {'$gte': 21}},
# {'tag': {'$in': ['foo', 'bar']}}
# ])])
# A little Django-ish querying can save smoe space, but can't do "or" conditions itself.
query = F(Person, name="Alice", age__ge=21) | Person.tag.any(["foo", "bar"])
# query = Filter([('$or', [
# OrderedDict([('name', 'Alice'), ('age', {'$gte': 21})
# ]), {'tag': {'$in': ['foo', 'bar']}}])])
from mongoengine import Document, StringField, IntField, ListField
class Person(Document):
name = StringField()
age = NumberField()
tag = ListField(StringField())
Q(name="Alice")
# <mongoengine.queryset.visitor.Q at 0x1059f9e80>
# Okay, the __repr__ is useless. :|
Q(name="Alice").to_query(Person)
# {'name': 'Alice'}
# Success! It absolutely requires concrete tanslation.
Q(age__gte=21).to_query(Person)
# {'age': {'$gte': 21}}
# No surprises here.
query = Q(name="Alice") & Q(age__gte=21) & Q(tag__in=("foo", "bar"))
# query = <mongoengine.queryset.visitor.QCombination at 0x105c96e48>
# Right.
badquery = query.to_query(Person)
# badquery = {'age': {'$gte': 21}, 'name': 'Alice', 'tag': {'$in': ['foo', 'bar']}}
# Now we have the raw, full query.
# Can't re-form from MongoDB version. :|
query = query & Q(age < 65)
query.to_query(Person)
# {'age': {'$gte': 21, '$lt': 65}, 'name': 'Alice', 'tag': {'$in': ['foo', 'bar']}}
query = Q(name="Alice") & Q(age__gte=21) | Q(tag__in=("foo", "bar"))
query.to_query(Person)
# {'$or': [
# {'age': {'$gte': 21}, 'name': 'Alice'},
# {'tag': {'$in': ['foo', 'bar']}}
# ]}
(query & Q(age__lt=65)).to_query(Person)
# {'$and': [{'$or': [{'age': {'$gte': 21}, 'name': 'Alice'},
# {'tag': {'$in': ['foo', 'bar']}}]},
# {'age': {'$lt': 65}}]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment