XUtils

Gmongo

A Groovy wrapper to the mongodb Java driver


Sorting and Pagination

@Grab(group='com.gmongo', module='gmongo', version='1.0')
import com.gmongo.GMongo

def mongo = new GMongo()
def db = mongo.getDB("gmongo")

// Make sure that the collection is empty
db.example.drop()

// Insert 100 documents with any random value
100.times {
    db.example << [time: it, random: (Integer)(Math.random() * 100)]
}

def at = 0

// Find out how many documents are in the collection
def total = db.example.find().count()

// Sort the documents by the 'random' property ascending and Paginate over it 10 by 10
while (at < total) {
    println "At page: ${at / 10}\n"
    db.example.find().limit(10).skip(at).sort(random: 1).each {
        println "\t-- ${it}"
    }
    println "\n--------------------------"
    at += 10
}

MapReduce

@Grab(group='com.gmongo', module='gmongo', version='1.0')
import com.gmongo.GMongo

def mongo = new GMongo()
def db = mongo.getDB("gmongo")

def words = ['foo', 'bar', 'baz']
def rand  = new Random()		

1000.times { 
    db.words << [word: words[rand.nextInt(3)]]
}

assert db.words.count() == 1000

def result = db.words.mapReduce(
    """
    function map() {
        emit(this.word, {count: 1})
    }
    """,
    """
    function reduce(key, values) {
        var count = 0
        for (var i = 0; i < values.length; i++)
            count += values[i].count
        return {count: count}
    }
    """,
    "mrresult",
    [:] // No Query
)

assert db.mrresult.count() == 3
assert db.mrresult.find()*.value*.count.sum() == 1000

Grouping

Grouping can also be achieved. Example:

@Grab("com.gmongo:gmongo:1.0")
import com.gmongo.GMongo

def gmongo = new GMongo("localhost:27017")

def db = gmongo.getDB("test")

db.clicks.drop()

db.clicks.insert(day: 1, total: 10)
db.clicks.insert(day: 1, total: 14)
db.clicks.insert(day: 2, total: 45)
db.clicks.insert(day: 1, total:  9)
db.clicks.insert(day: 3, total: 32)
db.clicks.insert(day: 2, total: 11)
db.clicks.insert(day: 3, total: 34)

def result = db.clicks.group([day: true], [:], [count: 0], "function(doc, out) { out.count += doc.total }")

// Will output [[day:1.0, count:33.0], [day:2.0, count:56.0], [day:3.0, count:66.0]]
println result

And a more advanced grouping using ‘keyf’:

@Grab("com.gmongo:gmongo:1.0")
import com.gmongo.GMongo

def gmongo = new GMongo("localhost:27017")

def db = gmongo.getDB("test")

db.clicks.drop()

db.clicks.insert(day: 1, total: 10)
db.clicks.insert(day: 1, total: 14)
db.clicks.insert(day: 2, total: 45)
db.clicks.insert(day: 1, total:  9)
db.clicks.insert(day: 3, total: 32)
db.clicks.insert(day: 2, total: 11)
db.clicks.insert(day: 3, total: 34)

def keyf = "function(clicks) { return clicks.day % 2 ? { odd: true } : { even: true } }"

def command = ['$keyf': keyf, cond: [:], initial: [count: 0], $reduce: "function(doc, out) { out.count += doc.total }"]

def result = db.clicks.group(command)

// Will output [[odd:true, count:99.0], [even:true, count:56.0]]
println result  

Aggregation

This features is only available in version 1.0 or greater.

The simple example below will get the name of all the cities with population greater or equal 10.000 and sort it.

@Grab("com.gmongo:gmongo:1.0")
import com.gmongo.GMongo

def gmongo = new GMongo("localhost:27017")

def db = gmongo.getDB("test")

db.zipcodes.drop()
db.zipcodes << ["city": "ACMAR", "loc": [-86.51557F, 33.584132F], "pop": 6055, "state": "AL", "_id": "35004"]
db.zipcodes << ["city": "ADAMSVILLE", "loc": [-86.959727F, 33.588437F], "pop": 10616, "state": "AL", "_id": "35005"]
db.zipcodes << ["city": "ADGER", "loc": [-87.167455F, 33.434277F], "pop": 3205, "state": "AL", "_id": "35006"]
db.zipcodes << ["city": "KEYSTONE", "loc": [-86.812861F, 33.236868F], "pop": 14218, "state": "AL", "_id": "35007"]
db.zipcodes << ["city": "NEW SITE", "loc": [-85.951086F, 32.941445F], "pop": 19942, "state": "AL", "_id": "35010"]

def aggrOutput = db.zipcodes.aggregate([ 
    $project : [ city: 1, pop: 1 ] 
  ],
  [ 
    $match : [ pop: [ $gte : 10 * 1000 ] ] 
  ],
  [ 
    $sort: [ pop: -1] 
  ]
)

assert aggrOutput.results().size() == 3
assert aggrOutput.results()[0].city == "NEW SITE"
assert aggrOutput.results()[1].city == "KEYSTONE"
assert aggrOutput.results()[2].city == "ADAMSVILLE"

An amazing documentation about Aggregation can be found in the MongoDB website: http://docs.mongodb.org/manual/applications/aggregation/ .

Maven

All versions of the project can be found in the maven central repository:

http://repo1.maven.org/maven2/com/gmongo/gmongo/

Build

The project is build using gradle. Gradle can be found in: http://www.gradle.org

Test

To run the tests start a mongo instance on localhost:27017


Articles

  • coming soon...