When querying MongoDB using mongoengine
it returns result with minor differences to what I expect. One of the important ones is $oid
which is returned but I don't like it:
"_id": {
"$oid": "5e3c0f7f284137537bf7c994"
},
Is there a way to project differently in mongoengine
? What I want is a simple id field:
"id": "5e3c0f7f284137537bf7c994"
EDIT1:
When I want to get string version of ID
I can use .id
to get let's say "5e3c0f7f284137537bf7c994"
. But problem is where I want to get the whole document:
MyModel.objects.all()
This query returns a list of all documents from MyModel
, BUT list of documents contain $oid
rather than string version of _id
. How should I get _id as is NOT $oid.
You need to use aggregate
method with $toString operator
pipeline = [
{"$addFields" : {"_id" : {"$toString" : "$_id"} } }
]
data = MyModel.objects().aggregate(pipeline)
http://docs.mongoengine.org/guide/querying.html#mongodb-aggregation-api
Note: This won't return MyModel
instance, you lose mongoengine
features
But, if you do not want lose features (works only for to_json
):
from bson import json_util, son
..
class MyModel(Document):
content = StringField(required=True)
#setup your attributes
def to_json(self, *args, **kwargs):
raw = self.to_mongo()
tmp = [(k, str(raw[k]) if k == "_id" else raw[k]) for k in raw]
return json_util.dumps(son.SON(tmp), *args, **kwargs)
...
# This returns <class 'mongoengine.queryset.queryset.QuerySet'>
data = MyModel.objects()
print(data[0])
print(data[0].to_json())
print(data.to_json())
print("[%s]" % ",".join([foo.to_json() for foo in data]))
----
MyModel object
{"_id": "5e400e737db7d0064937f761", "content": "foo"}
[{"content": "foo", "_id": {"$oid": "5e400e737db7d0064937f761"}}, {"content": "bar", "_id": {"$oid": "5e400e737db7d0064937f762"}}]
[{"_id": "5e400e737db7d0064937f761", "content": "foo"},{"_id": "5e400e737db7d0064937f762", "content": "bar"}]