问题
I currently have an social game app using mongodb for it's database. My question is what are some suggestions if I want to create a points and badging system. The business logic for achievements/badges could become quite complicated and are very ad-hoc so doing real-time awarding of badges would not seem efficient. I am imagining adding tracked actions to a queue somewhere, i.e. Amazon SQS, or just using a user's activity feed as a queue, and have another offline worker process going through and just processing the effects of every action/activity to see if the threshold for any particular badge is crossed.
My worry with this method is that it seems like the badge queries can become quite intensive and I'd also have to track a very large number of actions. I can envision achievements ranging from things like a badge for someone that's scored 2nd place every week for the past 4 weeks, or a badge for someone that has a friend in every single one of 50 states... etc...
Are there more elegant or tried-and-true methods for this type of stuff? Would it make sense to use another database for achievements/activity feed/leaderboards besides mongo, creating a mongo/other db hybrid environment?
Are choices like Redis, Neo4J, or just plain old SQL Server a good choice for a hybrid solution? I like Mongo so that will stay as our primary db, but curious to see if adding another db to the mix would help.
回答1:
This is a good candidate for running map reduce on the database. you can run them on a less regular basis, using them for offline computation of the data that you want.
http://www.mongodb.org/display/DOCS/MapReduce
You could use other tools to do this, but in your summary i cannot see any compelling reason to add complexity at this stage. I would explore map reduce, try it out and then if it does not meet your needs, expand your options. but at that time, you would at least have identified concrete bottlenecks, if any.
回答2:
Just some notes on using a graph-db like Neo4j. As your badge information is always? queried for a concrete user these are local and not global queries.
So if you can model your domain as network of objects (as it perhaps already is) and express your badge logic as a set traversals or graph-queries starting at the user then it works without persisting them as local graph queries are fast enough regardless of data set size.
Easiest thing is to create a time-boxed PoC to see if that works for you. Cross-connecting the two stores by storing your user-id in an graph-db index and as property on the node should work fairly easily. You can sync the db's on the commit/save hooks or asynchronously. Perhaps it would be sensible to move other "social-network" data into the graph as well and keep the game data + documents in mongodb.
来源:https://stackoverflow.com/questions/8008820/how-to-architect-achievements-and-badging-with-nosql