0

I am trying to execute an upsert function in mongoengine. That is, if a document is present, I want to update it with new values, and if it isn't present, I want to create and insert.

I have list of objects. These objects can or cannot have ObjectIds. Example is:

[
    {
        "id" : ObjectId("5c1791b7397df4a9c8518342"),
        "type": "Line"
    },
    {
        "type": "Line"
    }
]

As you can see the second object does not have an Id.

I have written my query as:

updates = Collection.objects(
    id=obj.get('id', None)).modify(
        new=True, 
        upsert= True, 
        **update_dict
    )

obj is each object when I iterate through the list.

Note: update_dict is another dict that gets its value from a function that returns the attributes to set. (For example: set__type: "Line")

Problem

The first object is getting modified just fine. However there is an error:

"'None' is not a valid ObjectId, it must be a 12-byte input or a 24-character hex string"

Clearly it's because of the obj.get('id', None) part.

So, is there a way that an id can be generated if it is passed as None?

hrishikeshpaul
  • 459
  • 1
  • 11
  • 27

1 Answers1

0

I tried same thing with mongoose and nodejs and it works for me if i am using like below:

Here is i my array Object:

           var arr = [
                {
                    _id: "5c13de7d47zfe91e3484362f",
                    email: 'test1@gmail.com',
                },
                {
                    _id: "5c13de7d47zfe91e3484362f",
                    email: 'test2@gmail.com',
                },
                {
                    // _id: "5c66aa87751fz5368759f9bc",   // Commented 
                    email: 'test3@gmail.com',
                }
            ]

Now i am iterating through the array as below with nodejs.

        arr.forEach(async element => {
            await Driver.findOneAndUpdate(
                {
                    _id: Types.ObjectId(element._id) 
                },
                {
                    email: element.email
                },{ upsert: true, new: true }
            ).lean().exec();
        });

And it works for me. It's updating documents in first two cases and inserting new doc for last case. The main thing is to use Types.ObjectId which is used to specify a type of ObjectId. If i am doing it without specifying Schema.Types.ObjectId then it does not working.

Jitendra
  • 3,135
  • 2
  • 26
  • 42