UPDATED: 8/26/11 - Check out our wiki for more up to date information on Using MongoDB with Moai Cloud

The native data store for Moai Cloud applications is the NoSQL database mongoDB (www.mongodb.org). Unlike traditional relational databases with tables and fields, mongoDB is a 'document store' that can store and query JSON documents and/or serialized Lua tables directly without the need for an ORM. Each Moai Cloud user account is allocated a private mongoDB database that is shared among all Moai Cloud services owned by that account. Your mongoDB database is exposed to Moai Cloud services via the mongodb object in the Moai Cloud Lua Environment.

Inserting a new document

Inserting a new document into your mongodb database is accomplished by the mongodb.insert(...) method. The insert method takes two arguments, a namespace and a Lua table or JSON document to insert. For example, if you wish to insert a JSON document representing a user's score for a game, you would do something like this:

mongodb:insert(‘high_scores', "{player_id:'1234', game_id:'7890', score:'102541'}")

Alternately, if you wanted to insert the same document using a Lua table, you could accomplish the same insert as above with the following code:


local score = {player_id='1234', game_id='7890', score='102541'} mongodb:insert(‘high_scores', score)</pre> Tip: For all practical purposes, mongoDB does not support the notion of unique keys. Therefore, if you call insert(...) multiple times with the same value, two copies of the document will be added to the collection. <h4>Finding documents</h4> Locating a document or documents in your mongodb database is done via the mongodb.query(...) method and a resulting cursor object. The query(...) method takes two arguments, a namespace as above, and a Lua table or JSON document describing in whole or in part the documents you wish to retrieve. If you wanted to find all of the high score documents in the high_scores collection belonging to a given user you could do the following: <pre class="brush:lua" gutter="false" />local cursor = mongodb:query(‘high_scores', {player_id='1234'})</pre> Once the query has executed, you can iterate over the results using the returned cursor object: <pre class="brush:lua" gutter="false" />while cursor:has_more() do local score = cursor:next() print( score.player_id ) print( score.game_id ) print( score.score ) end</pre> If you want to retrieve scores for more than one user at a time, you can use the mongoDB '$or' keyword. For example:


local cursor = mongodb:query(‘high_scores', {['$or'] = {{player_id='1234'}, {player_id='2345'}})</pre> More information about mongoDB queries and various keywords available can be found on the 'Advanced Queries' page on the mongoDB website.

Removing documents

Removing a document from your mongoDB database is accomplished by the mongodb.remove(...) method. The remove method takes three arguments, a namespace, a query and a flag. The namespace argument is identical to that described above. The query is a Lua table or JSON document that describes in whole or in part the document(s) you wish to remove from a collection. The flag ('justOne') when set to true will cause the driver to remove at most one document satisfying the query. If this flag is set to false, all documents satisfying the query will be removed. Given the document structure described in "Inserting a new document", if you wanted to remove all scores in the high_scores collection for game_id '7890' you could do the following:


mongodb:remove(‘high_scores', {game_id='7890'}, false)</pre> If you wanted to remove only the high scores for player_id '1234' for game_id '7890' you could do the following:


mongodb:remove(‘high_socres', {player_id='1234', game_id='7890'})</pre> <h4>Updating documents</h4> Updating a document in your mongoDB database is accomplished, unsurprisingly, by the mongob.update(...) method. Similar to remove(...), update(...) takes a namespace and a query as it's first two arguments. The third argument, "modifier" is a Lua table or JSON document describing the update to make to the document or documents satisfying the query. Caveat: By default, an update will replace the document or documents satisfying the query with the contents of "modifier". The fourth argument "upsert" if true will instruct the driver to insert a new document described by the "modifier" argument if no other documents satisfy the specified query. Finally, the fifth argument "multi", if false, will instruct the driver to either update only the first document found that satisfies the query. If "multi" is true, all documents satisfying the query will be updated. If you wish to replace the high score entry described above with a new one, you could do the following: <pre class="brush:lua" gutter="false" />mongob:update(‘high_scores', {player_id='1234', game_id='7890', score='102541'}, {player_id='1234', game_id='9990', score='6540'}, false, false)</pre> Replacing an entire document however, is rarely what you want. Typically one wants to update only a single field in a given document. To accomplish this, you can either describe the entire document to update as the "modifier" or you can use the mongoDB keyword $set to update only a subset of fields. For example, if you wish to update only the high score based on player_id and game_id, you could do the following: <pre class="brush:lua" gutter="false" />mongodb:update(‘high_scores', {player_id='1234', game_id='7890'}, {['$set']={score='200050'}}, false, false)</pre> <h4>Namespaces</h4> Many of the mongoDB methods take a namespace as a parameter. A mongoDB namespace in Moai Cloud is effectively name of a collection. (e.g. high_scores). However, when viewing the associated data in your database via the database admin tool (see below), you’ll notice that all collection names are prefixed with the route (path) of your service. This is done automatically for the purpose of isolating service data in the case where you have mutliple services running under the same Moai Cloud account. You do not need to add this prefix yourself when calling mongodb methods. <h4>Under the Hood</h4> In the Moai Cloud environment, mongoDB services are provided using the open source driver, <a title="luamongo" href="https://github.com/moai/luamongo" target="_blank">luamongo</a>. For more information about what methods and functionality are exposed via the luamongo driver, visit the <a title="project page on GitHub" href="https://github.com/moai/luamongo" target="_blank">project page on GitHub</a>. <h4>Administering Your Database</h4> On the Moai Cloud dashboard, you can find a link for “Database Admin.” This link will open a mongoDB administrative interface called RockMongo that will allow you to view, modify, download, export and/or migrate your database data.'</p>'