Procedural update of multiple documents for tick-based game

7 views
Skip to first unread message

jannick

unread,
Nov 18, 2010, 12:51:19 PM11/18/10
to mongodb-user
Hi

I'm evaluating mongo-db for a tick-based game where I need to update a
lot of documents each time the game "ticks". These updates a related
to a sort of commodity exchange, where the prices can change for each
tick. Players can place orders to be executed once certain market
conditions are met, and it is these orders I need to evaluate for each
tick. My current idea is to represent the state of each player with
documents of the form:

{
credits: 200,
inventory:
[
{name: "gold", quantity: 125 }
],
orders:
[
{ type: "sell", name: "gold", limit: 15, quantity: 20}
{ type: "sell", name: "gold", limit: 40, quantity: 50}
{ type: "buy", name: "silver", limit: 30, quantity: 50}
],
order_count: 3
}

for each tick I then need to:
1) find documents where order_count > 0
2) for each of these documents evaluate the orders and credits fields
against context data: "game time" and a table with commodity-prices
3) do a per-document atomic-update if buy/sell conditions are met

I have so far prototyped this by:
1) Query to find potential documents:
db.gamestate.find({ "order_count" : { $gt: 0} } );
2) Load each document to java backend, and evaluate against price
data
3) Update using atomic operators:
db.game.update(
{credit: {$gt: 50}, "inventory.name": "gold", orders: {name:
"gold", quantity: 25, type: "buy", limit: 50 }},
{$inc: {credit: -50}, $inc: {"inventory.$.quantity": 25},
$inc: {order_count: -1}, $pull: {orders: {name: "gold", quantity:
25, type: "buy", limit: 50 }}} );

This approach does however have a number of problems:
1) I need to transfer a lot of full documents out of the server to
do the evaluation. At any given tick, only a few of them is likely to
be triggered.
2) Nasty atomic update, and it even depends on the 'inventory' field
being pre-polutated with entries for each commodity in existence,
since the positional operator depends on finding an existing entry.

Seems to me what is really needed is a sort of multi-update with a
procedure to atomically calculate and apply the update for each
document that matches the overall criteria for consideration. I've
been looking at using map/reduce and db.eval but neither seems to fit
the description. In map/reduce the doc and forum suggest you are not
able/supposed to manipulate the db, and the db.eval documentation
suggests that db.eval blocks other operations. Any solution should
preferably work with sharding as well.

Okay, that was a lot of background info. My hope was you could help
answer the following questions:
1) The db.eval doc says "In 1.7.2, a nolock option was added to
db.eval". Can anyone expand on that, and does it mean that db.eval
would be a fit for my requirements?
2) Are there other approaches that would be a better way to solve the
problem?

Thanks

Eliot Horowitz

unread,
Nov 23, 2010, 1:49:34 AM11/23/10
to mongod...@googlegroups.com
1) I think you actually want the current/default behavior of locking.
That way you can do a number of things atomically.
2) This is something we are looking into added features for, but there
aren't great solutions today.

> --
> You received this message because you are subscribed to the Google Groups "mongodb-user" group.
> To post to this group, send email to mongod...@googlegroups.com.
> To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.
>
>

Reply all
Reply to author
Forward
0 new messages