my application has a list of the games. Each game has a position(in which order to show it to users: 1, 2, 3...).
I'm using MongoDB to keep all the data. Ok, so now I have the game with position 4 for example. And I want to change it to position 1. So what I need to do?
I need to update field position for this game in MongoDB from 4 to 1, and to do increment to all documents in this collection that following after position 1.
But I think it's not very good idea! May be you have ideas how to implement it in better way? Thanks!
Example of the mongo table:
_id | name | description | position |
________________________________________________________
ObjectId("...") | bubble | some description | 1
ObjectId("...") | bubbleA | some description | 2
ObjectId("...") | bubbleB | some description | 3
ObjectId("...") | bubbleC | some description | 4
ObjectId("...") | bubbleD | some description | 5
ObjectId("...") | bubbleE | some description | 6
ObjectId("...") | bubbleF | some description | 7
So now in my site I'm showing games in order: bubble -> bubbleA -> bubbleB -> bubbleC... And now I want to show in my site games in order: bubbleC -> bubbleA -> bubbleB -> bubble... So to do it I need to update "position" field in my table for "bubbleC" to "1", and increment all other "positions" for all documents after document with name "bubble". But it's a bad idea. So how to do it better?
Your approach isn't that bad if you have a relatively small number of documents and don't change positions a lot.
As an alternative you could store the positional metadata in a separate array. Position updates would only touch one document. Basic Python example:
def move(positions, old_index, new_index):
element = positions.pop(old_index)
positions.insert(new_index, element)
return positions
# Fetch array from MongoDB (or from anywhere really)
positions = [
{ '_id': 'ObjectId("...")', 'name': "bubble", 'description': "some description" },
{ '_id': 'ObjectId("...")', 'name': "bubbleA", 'description': "some description" },
{ '_id': 'ObjectId("...")', 'name': "bubbleB", 'description': "some description" },
{ '_id': 'ObjectId("...")', 'name': "bubbleC", 'description': "some description" },
{ '_id': 'ObjectId("...")', 'name': "bubbleD", 'description': "some description" },
{ '_id': 'ObjectId("...")', 'name': "bubbleE", 'description': "some description" },
{ '_id': 'ObjectId("...")', 'name': "bubbleF", 'description': "some description" }
]
old_index = 3
new_index = 0
move(positions, old_index, new_index)
# New positions:
#
# [{'_id': 'ObjectId("...")', 'description': 'some description', 'name': 'bubbleC'}, <--
# {'_id': 'ObjectId("...")', 'description': 'some description', 'name': 'bubble'},
# {'_id': 'ObjectId("...")', 'description': 'some description', 'name': 'bubbleA'},
# {'_id': 'ObjectId("...")', 'description': 'some description', 'name': 'bubbleB'},
# {'_id': 'ObjectId("...")', 'description': 'some description', 'name': 'bubbleD'},
# {'_id': 'ObjectId("...")', 'description': 'some description', 'name': 'bubbleE'},
# {'_id': 'ObjectId("...")', 'description': 'some description', 'name': 'bubbleF'}]
Writing a small helper function would help with moving elements around by _id or name.