2
votes

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.

1
.id should return string id by defaultValijon
@Valijon thank you for your note. What I want is that when I find a document it returns all fields along side _id which in the format I mentioned in the question. I need to reformat it.Alireza
did you try just .Class.objects.get(condition).id ?Valijon
@Valijon please take a look at the EDIT1 section of question. Thanks.Alireza
take a look my answerValijon

1 Answers

-1
votes

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