I have a database with the following schema:
[
image: {
image_name: str,
date: date,
labels: [
label: {
label_name: str,
version: int,
features: [
feature: {
feature_name: str,
geometry: Polygon,
},
...
]
},
...
]
},
...
]
I am writing an API for this database, and I am trying out MongoEngine. I define my documents as follows:
class Feature(EmbeddedDocument):
feature_name = StringField(required=True)
geometry = PolygonField(required=True)
id = ObjectIdField(required=True, default=ObjectId, unique=True, primary_key=True)
class Label(EmbeddedDocument):
label_name = StringField(required=True)
version = IntField(required=True)
features = EmbeddedDocumentListField(Feature)
id = ObjectIdField(required=True, default=ObjectId, unique=True, primary_key=True)
class Image(Document):
image_name = StringField(required=True)
date = DateTimeField(required=True)
labels = EmbeddedDocumentListField(Label)
I would like to access a specific embedded document.
I can access a top-level document this way:
image = next(Image.objects(id=image_id))
But this doesn’t work for embedded documents:
label = next(Label.objects(id=label_id)) # AttributeError: type object 'Label' has no attribute 'objects'
Prior to using MongoEngine, I was using the following code with PyMongo:
# PyMongo code to get label based on label_id
pipeline = [
{"$unwind": "$labels"},
{"$match": {"labels._id": label_id}},
{"$project": {"label": "$labels"}},
]
label_dict = next(cursor)["label"] # returns a dict
label = Label.from_dict(label_dict)
# PyMongo code to get feature based on feature_id
pipeline = [
{"$unwind": "$labels"},
{"$unwind": "$labels.features"},
{"$match": {"labels.features._id": feature_id}},
{"$project": {"feature": "$labels.features"}},
]
cursor = self.db.images.aggregate(pipeline)
feature_dict = next(cursor)["feature"] # returns a dict
feature = Feature.from_dict(feature_dict)
What would be the best solution using MongoEngine?
Many thanks in advance for your help!
Thibaut