Closed partyzan closed 10 years ago
Device.objects.filter(transactions__transaction_id=tid).find_all()
Should work... ;/ If you pass a single element we'll try to find the element in the collection, if you pass a list we'll match only if the entire list matches.
Unfortunately it doesn't :/ I am using the following to test:
@gen_test()
def test_embedded_lookup(self):
class Embedded(Document):
eid = StringField()
class Base(Document):
bid = StringField()
embedded_items = ListField(EmbeddedDocumentField(Embedded))
base = yield Base.objects.create(bid="b1", embedded_items=[Embedded("e1")])
result = yield Base.objects.filter(embedded_items__eid="e1").find_all()
self.assertIsNotNone(result)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].bid, base.bid)
self.assertEqual(len(result[0].embedded_items), 1)
self.assertEqual(result[0].embedded_items[0].eid, "e1")
This kind of query (not using Q) fails with the following error:
ValueError: Invalid filter 'embedded_items__eid': Invalid operator (if this is a sub-property, then it must be used in embedded document fields).
If using the same query in Q and passing it to filter it just returns an empty list.
This syntax works for a single embedded document query, but not for list of embedded documents.
@gen_test
def test_embedded_lookup(self):
class Embedded(Document):
eid = StringField()
class Base(Document):
bid = StringField()
embedded = EmbeddedDocumentField(Embedded)
base = yield Base.objects.create(bid="b1", embedded=Embedded(eid="e1"))
self.assertIsNotNone(base)
self.assertEqual(base.bid, "b1")
self.assertIsNotNone(base.embedded)
self.assertEqual(base.embedded.eid, "e1")
result = yield Base.objects.filter(embedded__eid="e1").find_all()
self.assertIsNotNone(result)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].bid, base.bid)
self.assertIsNotNone(result[0].embedded)
self.assertEqual(result[0].embedded.eid, base.embedded.eid)
I have verified that the same syntax does work for mongoengine:
class Embedded(EmbeddedDocument):
eid = StringField()
class Base(Document):
embedded = ListField(EmbeddedDocumentField(Embedded))
bid = StringField()
base = Base(bid="b1",embedded=[Embedded(eid="e1")])
base.save()
result = Base.objects(embedded__eid="e1")
The Base object is found and retrieved.
Can I work around this issue in some way ? Can I pass a raw query to motorengine ?
I'm fixing it, but first I'm introducing a way of doing raw queries, so we can work around other issues that may arise.
I'm doing it right now, will have a version by tonight.
Awesome! Thanks.
Released on version 0.8.7. Can you please confirm if this has fixed it? Anyways, I updated the docs with how to do raw queries. Sorry for all the inconvenience this has caused you.
(forgot to link the docs)
http://motorengine.readthedocs.org/en/latest/getting-and-querying.html#querying-with-raw-queries
Thanks! It's working now.
Taking a simple structure of:
I am trying to understand how can I query the devices collection based on the fields of the embedded transaction.
In mongo shell the simple find does the trick:
I have tried the following:
How can I perform such a query through motorengine ? How can I perform a more complicated query to match on multiple fields ($elemMatch style) ?