3

I need to implement the FIFO logic with MongoDB collection:

  1. Pop the first document from MongoDB collection.
  2. Push the document to MongoDB collection and place it as a last document.

The documents in collection do not have any indexes except auto-generated _id (ObjectId).

I wonder, is it possible to findAndRemove the first document from collection and to guarantee that push and pop operations will perform as FIFO stack atomically?

I know that it is possible to do with an array inside document with atomic push and pop operations, but the main problem is that if I will store all my data inside 1 document's array, it's size will exceed 16MB (the maximum allowed size of MongoDB document)

Thanks in advance, Valentin

Valentin
  • 860
  • 2
  • 10
  • 21

2 Answers2

5

If you're accessing your stack from a single machine you can do so using findAndRemove :

db.col.findAndModify({query:{}, sort:{i: -1}, remove:true})

This will return the removed value and remove the document itself atomically per your request. Where "i" is a time sorted field (_id works if it is an ObjectId). If you're using the FIFO stack/collection from multiple instances you will have to ensure somehow that the "i" values are atomically increased across all instances or you will have to live with the collection being FIFO-ish rather than strictly so.

Remon van Vliet
  • 18,365
  • 3
  • 52
  • 57
  • Note: findAndModify only apply on one document. http://stackoverflow.com/questions/19065615/how-to-delete-n-numbers-of-documents-in-mongodb if more than one document needs to be removed. – The Demz Mar 28 '17 at 21:10
2

Because document _id is the value of the document creation date, you can sort documents to retrieve the first/last created. To get the last created document you could do:

db.collection.find().sort({ _id : -1 }).limit(1)

And then, adding a document to the collection will add it at the collections end.

yves amsellem
  • 7,106
  • 5
  • 44
  • 68