Search code examples
mongodbprojectionmongoengine

Is there a way to change MongoDB _id field name in MongoEngine from $oid to $id?


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.


Solution

  • 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"}]