Add numerically-ordered index feature which forces a field to maintain ordering
I would like MongoDB to add better support for ordered lists across documents in a collection. This feature would allow the user to designate a field such as "position", and the DB would ensure the values of that field across documents remain in a monotonically-increasing integer sequence 0, 1, 2, 3, ... N.
I am the maintainer of a Ruby library called "Mongoid Orderable". This library makes numerically ordered field across documents. I'd like to ask MongoDB to investigate moving the functionality of this library to the server.
What use case would this feature/improvement enable?
This feature would be useful in a wide-variety of real world applications; ordered lists are extremely common. In my app (standard SaaS related to restaurant management) I have at least 20 instances of such ordered lists.
Suggested implementation
I propose to do this using a new "ordered" index type.
For example, suppose my application has many Car documents, and I want to maintain the "position" of the Cars in a consistent order for each Dealer.
I add the following index to the Car collection:
Cars -> createIndex({ dealer_id: 1, position: 1 }, { ordered: 1 })
Then in my Car collection, I see:
Car A -> dealerid: ***, position: 0
Car B -> dealerid: **, position: 1
Car C -> dealer_id: **, position: 2
Car D -> dealerid: yyy, position: 0
Car E -> dealerid: yyy, position: 1
Due to this special "ordered" index, the position field will always maintain a zero-based ordered value for the given scope. If I modify any member, this ordering is preserved:
Change Car C position
Car C -> updateOne(position: 1)
Car A -> dealerid: ***, position: 0
Car B -> dealerid: **, position: 2 <-- updated
Car C -> dealer_id: **, position: 1 <-- updated
Car D -> dealerid: yyy, position: 0
Car E -> dealerid: yyy, position: 1
Change Car C dealer_id
Car C -> updateOne(dealer_id: yyy)
Car A -> dealerid: ***, position: 0
Car B -> dealerid: ***, position: 1 <-- updated
Car C -> dealerid: yyy, position: 1 <-- updated
Car D -> dealerid: yyy, position: 0
Car E -> dealer_id: yyy, position: 2 <-- updated
Change Car C position to be a very large value
Car C -> updateOne(position: 999)
Car A -> dealerid: ***, position: 0
Car B -> dealerid: ***, position: 1
Car C -> dealerid: yyy, position: 2 <-- updated, stays in order
Car D -> dealerid: yyy, position: 0
Car E -> dealer_id: yyy, position: 1 <-- updated
Change Car C position to a non-numeric value
Car C -> updateOne(position: "foo")
update is ignored; nothing changes
This feature should work with partial filter expressions, etc.