Skip to content
Advertisement

Query by computed property in python mongoengine

I wondered if it is possible to query documents in MongoDB by computed properties using mongoengine in python.

Currently, my model looks like this:

class SnapshotIndicatorKeyValue(db.Document):
    meta = {"collection": "snapshot_indicator_key_values"}

    snapshot_id = db.ObjectIdField(nullable=False)
    indicator_key_id = db.ObjectIdField(nullable=False)
    value = db.FloatField(nullable=False)
    created_at = db.DateTimeField()
    updated_at = db.DateTimeField()

    @property
    def snapshot(self):
        return Snapshot.objects(id=self.snapshot_id).first()

    def indicator_key(self):
        return IndicatorKey.objects(id=self.indicator_key_id).first()

When I do for example SnapshotIndicatorKeyValue .objects().first().snapshot, I can access the snapshotproperty.

But when I try to query it, it doesn’t work. For example:

SnapshotIndicatorKeyValue.objects(snapshot__date_time__lte=current_date_time)

I get the error `mongoengine.errors.InvalidQueryError: Cannot resolve field “snapshot”“

Is there any way to get this working with queries? I need to query SnapshotIndicatorKeyValue based on a property of snapshot.

Advertisement

Answer

In order to query the snapshot property directly through mongoengine, you can reference the related snapshot object rather than the snapshot_id in your SnapshotIndicatorKeyValue document definition.

An amended model using a Reference field would be like this:

from mongoengine import Document, ReferenceField

class Snapshot(Document)
property_abc = RelevantPropertyHere() # anything you need

class SnapshotIndicatorKeyValue(Document):
snapshot = ReferenceField(Snapshot)

You would sucessively save an instance of Snapshot and an instance of SnapshotIndicatorKeyValue like this:

sample_snapshot = Snapshot(property_abc=relevant_value_here) # anything you need
sample_snapshot.save()

sample_indicatorkeyvalue = SnapshotIndicatorKeyValue()
sample_indicatorkeyvalue.snapshot = sample_snapshot
sample_indicatorkeyvalue.save()

You can then refer to any of the snapshot‘s properties through:

SnapshotIndicatorKeyValue.objects.first().snapshot.property_abc
Advertisement