I'm trying to create a query for my Aerospike database, that would return the highest value in a specific bin; similar to the way that the MAX() function works in MySQL. For example, if I had a set like this:
+--------------+---------+
| filename | version |
+--------------+---------+
| alphabet.doc | 4 |
| people.doc | 2 |
| alphabet.doc | 6 |
| people.doc | 3 |
+--------------+---------+
What I need is to only return the filename with the highest version number. At the moment I can add a filter like this:
stmt := db.NewStatement(DBns, DBset, "filename", "version")
stmt.Addfilter(db.NewEqualFilter("filename", "alphabet.doc"))
// run database query
records := runQuery(stmt)
Anyone know how to do this?
You can apply a Lua user-defined function (UDF) to the query to filter the results efficiently.
E.g. here is a Stream UDF that would return the record with the max. version number:
function maxVersion(stream, bin)
-- The stream function cannot return record objects directly,
-- so we have to map to a Map data type first.
local function toArray(rec)
local result = map()
result['filename'] = rec['filename']
result['version'] = rec['version']
return result
end
local function findMax(a, b)
if a.version > b.version then
return a
else
return b
end
end
return stream : map(toArray) : reduce(findMax)
end
Using the Go client you would execute the function like this:
stmt := NewStatement(ns, set)
recordset, _ := client.QueryAggregate(nil, stmt, "udfFilter", "maxVersion")
for rec := range recordset.Results() {
res := rec.Record.Bins["SUCCESS"].(map[interface{}]interface{})
fmt.Printf("filename with max. version: %s (ver. %d)\n", res["filename"], res["version"])
}
I've uploaded a fully working example as a Gist here: https://gist.github.com/jhecking/b98783bea7564d610ea291b5ac47808c
You can find more information about how to work with Stream UDFs for query aggregation here: http://www.aerospike.com/docs/guide/aggregation.html