mongoengine
mongoengine copied to clipboard
How to get all matched documents instead of the First Matching document.
Document Structure
Data
class Data(EmbeddedDocument):
v = FloatField()
q = StringField()
co2 = FloatField()
price = FloatField()
ts = DateTimeField()
Meters Data
class MetersData(DynamicDocument):
meta = {'collection': 'dk_heating'}
_id = ObjectIdField()
ident = StringField()
meteringPointId = StringField()
customer = StringField()
cvr = StringField()
type = StringField()
unit = StringField()
address = StringField()
period = EmbeddedDocumentField(Period)
hourly_data = ListField(EmbeddedDocumentField(Data), db_field='data')
daily_data = ListField(EmbeddedDocumentField(Data))
monthly_data = ListField(EmbeddedDocumentField(Data))
# monthly_data = EmbeddedDocumentListField(Data)
yearly_data = ListField(EmbeddedDocumentField(Data))
I am using this Query.
Query
MetersData.objects.filter(address=address, customer=customer).fields(
monthly_data={"$elemMatch": {"q": "E"}},
address=1, customer=1, cvr=1, ident=1, meteringPointId=1, type=1, unit=1, period=1)
It returns me only the first matching element. I have read the documentation and it reads that $elemMatch is supposed to return only the first matching result. But in my case, I need all the matching results.
Result of the Query
I have searched everywhere but I am unable to find a solution.
If I understand correctly, your problem is that the result of the query returns only the monthlyData element that are matched.
When you use $elemMatch in the .fields()
of MetersData.objects(...).fields()
, it gets use as a projection operator (as described here in the MongoDB doc). So the behavior that you see is expected and it only returns what's matched.
In your case you need to use it as a filter, thus in the .objects()
or .filters()
. This can be done with the elemMatch operator as in:
MetersData.objects(monthly_data__elemMatch={"q": "E"})
.
or with a raw query with __raw__
, as in
MetersData.objects(__raw__={"monthly_data":{"$elemMatch": {"q": "E"}}})
.
Let's keep this ticket opened as the doc could be improved
After a second thought, I'm not sure how to improve the doc and I think it's okay as it is because it specifies that it's the ``elemMatch projection operator