6

I am using pymongo to insert documents in the mongodb. here is code for router.py file

    temp = db.admin_collection.find().sort( [("_id", -1)] ).limit(1)
    for doc in temp:
        admin_id = str(int(doc['_id']) + 1)


    admin_doc ={
    '_id'       :   admin_id,
    'question'  :   ques,
    'answer'    :   ans,
    }
    collection.insert(admin_doc)

what should i do so that at every insert _id is incremented by 1.

Cristian Lupascu
  • 39,078
  • 16
  • 100
  • 137
Shivamshaz
  • 262
  • 2
  • 3
  • 10
  • What did you try so far? – Alexander Vogt Oct 22 '13 at 17:44
  • I used Cursors to get id of very last document inserted and increment 1 in that id. but it is not working. – Shivamshaz Oct 22 '13 at 17:55
  • With pymongo the insertion of "_id" is done for you automatically. Are you sure you really need to manually change it? It's mainly used as an internal unique variable for mongodb documents in a collection. You can just delete the key and mongo will generate a new unique one. There is no guarantee that ['_id'] + 1 is a new unique id. – RMcG Oct 22 '13 at 18:32
  • 1
    See answer to this question: http://stackoverflow.com/questions/8384029/auto-increment-in-mongodb-to-store-sequence-of-unique-user-id – Shad Oct 22 '13 at 19:21

3 Answers3

9

It doesn’t seem like a very good idea, but if you really want to go through with it you can try setup like below.

It should work good enough in a low traffic application with single server, but I wouldn't try anything like this with replicated or sharded enviroment or if you perform large amount of inserts.

Create separate collection to handle id seqs:

db.seqs.insert({
    'collection' : 'admin_collection',
    'id' : 0
})

Whenever you need to insert new document use something similar to this:

def insert_doc(doc):
    doc['_id'] = str(db.seqs.find_and_modify(
        query={ 'collection' : 'admin_collection' },
        update={'$inc': {'id': 1}},
        fields={'id': 1, '_id': 0},
        new=True 
    ).get('id'))

    try:
        db.admin_collection.insert(doc)

    except pymongo.errors.DuplicateKeyError as e:
        insert_doc(doc)
imrek
  • 2,930
  • 3
  • 20
  • 36
zero323
  • 322,348
  • 103
  • 959
  • 935
0

If you want to manually change the "_id" value you can do this by changing the _id value in the returned document. You could do this in a similar manner to the way you have proposed in your question. However I do not think this approach is advisable.

curs = db.admin_collection.find().sort( [("_id", -1)] ).limit(1)
for document in curs:
    document['_id'] = str(int(document['_id']) + 1)
    collection.insert(document)

It is generally not a good idea to manually make your own id's. These values have to be unique and there is no guarantee that str(int(document['_id']) + 1) will always be unique.

Instead if you want to duplicate the document you can delete the '_id' key and insert the document.

curs = db.admin_collection.find().sort( [("_id", -1)] ).limit(1)
for document in curs:
    document.pop('_id',None)
    collection.insert(document)

This inserts the document and allows mongo to generate the unique id.

RMcG
  • 1,045
  • 7
  • 14
0

Way late to this, but what about leaving the ObjectId alone and still adding a sequential id to use as a reference for calling the particular document(or props thereof) from a frontend api? I've been struggling to get the frontend to drop the "" on the ObjectId when fetching from the api.

Jowz
  • 399
  • 1
  • 3
  • 16
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 21 '21 at 05:05