Skip to content

Instantly share code, notes, and snippets.

@vanpelt
Created January 7, 2009 23:23
Show Gist options
  • Save vanpelt/44497 to your computer and use it in GitHub Desktop.
Save vanpelt/44497 to your computer and use it in GitHub Desktop.
{
fields: {awesome:'all', neat:'avg'},
data: {
awesome: 1,
other: 2,
neat: 3
},
worker_id: 123,
created_at: some_time,
type: 'Judgment',
unit_id: 1
}
function(doc) {
if(doc.type = "Judgment") {
emit([doc.job_id, doc.unit_id], doc)
}
}
function(keys, values, rereduce) {
var units = {}
if(rereduce) {
for(var i=0; i < values.length; i++){
for(var key in values[i])
units[key] = recombine(values[i][key], units[key] || {})
}
return units
}
function recombine(one, two) {
for(var key in one) {
if(two[key]) {
if(typeof(one[key]) != "string" && one[key].length)
one[key] = one[key].concat(two[key])
else if(typeof(one[key]) == "object") {
var opp = null
for(var k in one[key]) { if(k != "res") opp = k }
one[key] = op(one[key].res.concat(two[key].res), opp)
}
}
}
return one
}
function combine(fresh, agg) {
agg = agg || {}
for(var key in fresh) {
agg[key] = agg[key] || []
agg[key].push(fresh[key])
}
return agg
}
function average(what) {
var sum = 0
for(var i = 0; i < what.length; i++) { sum += parseFloat(what[i]) }
return {avg: Math.round((sum / what.length) * 100)/100, res: what}
}
function aggregate(what) {
var counts = {}
for(var i = 0; i < what.length; i++) {
counts[what[i]] = counts[what[i]] || 0
counts[what[i]] += 1
}
var winner = [null, 0]
var res = []
for(var count in counts) {
for(var i = 0; i < counts[count]; i++) { res.push(count) }
if(counts[count] > winner[1])
winner = [count, counts[count]]
}
return {agg: winner[0], res: res}
}
//This is the combo logic... (either avg, max, or min numbers, pick the most common(agg), or all)
function op(what, op) {
if(op == "max" || op == "min") {
var nums = [], h = {}
for(var i = 0; i < what.length; i++) { nums.push(parseFloat(what[i].replace(/[$ ,]/g,''))) }
h[op] = Math[op].apply(Math, nums)
h["res"] = what
return h
} else if(op == "avg")
return average(what)
else if(op == "agg")
return aggregate(what)
else
return what
}
function process(obj, fields) {
for(var key in obj) {
if(key == "_workers" || key == "_created_at" || fields[key])
obj[key] = op(obj[key], fields[key])
else
obj[key] = obj[key][0]
}
return obj
}
var last_key = false
for(var i = 0; i < keys.length; i++) {
var key = keys[i][0][1]
if(last_key && key != last_key)
units[last_key] = process(units[last_key], values[i].fields)
values[i].data._workers = values[i].worker_id
values[i].data._created_at = values[i].created_at
//Assure every field is defined... LAME
for(var f in values[i].fields) { values[i].data[f] = (values[i].data[f] == undefined ? null : values[i].data[f]) }
units[key] = combine(values[i].data, units[key])
last_key = key
}
units[last_key] = process(units[last_key], values[keys.length-1].fields)
return units
}
{
_workers: [1,2,3],
_created_at: [time, time, time],
awesome: [1,2,3],
other: 2,
neat: {avg: 3.33, res: [1,4,5]}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment