Godeps/_workspace/src/gopkg.in/mgo.v2/session.go
func (q *Query) MapReduce(job *MapReduce, result interface{}) (info *MapReduceInfo, err error) {
	q.m.Lock()
	session := q.session
	op := q.op // Copy.
	limit := q.limit
	q.m.Unlock()

	c := strings.Index(op.collection, ".")
	if c < 0 {
		return nil, errors.New("Bad collection name: " + op.collection)
	}

	dbname := op.collection[:c]
	cname := op.collection[c+1:]

	cmd := mapReduceCmd{
		Collection: cname,
		Map:        job.Map,
		Reduce:     job.Reduce,
		Finalize:   job.Finalize,
		Out:        fixMROut(job.Out),
		Scope:      job.Scope,
		Verbose:    job.Verbose,
		Query:      op.query,
		Sort:       op.options.OrderBy,
		Limit:      limit,
	}

	if cmd.Out == nil {
		cmd.Out = bson.D{{"inline", 1}}
	}

	var doc mapReduceResult
	err = session.DB(dbname).Run(&cmd, &doc)
	if err != nil {
		return nil, err
	}
	if doc.Err != "" {
		return nil, errors.New(doc.Err)
	}

	info = &MapReduceInfo{
		InputCount:  doc.Counts.Input,
		EmitCount:   doc.Counts.Emit,
		OutputCount: doc.Counts.Output,
		Time:        doc.TimeMillis * 1e6,
	}

	if doc.Result.Kind == 0x02 {
		err = doc.Result.Unmarshal(&info.Collection)
		info.Database = dbname
	} else if doc.Result.Kind == 0x03 {
		var v struct{ Collection, Db string }
		err = doc.Result.Unmarshal(&v)
		info.Collection = v.Collection
		info.Database = v.Db
	}

	if doc.Timing != nil {
		info.VerboseTime = doc.Timing
		info.VerboseTime.Total *= 1e6
		info.VerboseTime.Map *= 1e6
		info.VerboseTime.EmitLoop *= 1e6
	}

	if err != nil {
		return nil, err
	}
	if result != nil {
		return info, doc.Results.Unmarshal(result)
	}
	return info, nil
}
func (q *Query) MapReduce(job *MapReduce, result interface{}) (info *MapReduceInfo, err error) {
	q.m.Lock()
	session := q.session
	op := q.op // Copy.
	limit := q.limit
	q.m.Unlock()

	c := strings.Index(op.collection, ".")
	if c < 0 {
		return nil, errors.New("Bad collection name: " + op.collection)
	}

	dbname := op.collection[:c]
	cname := op.collection[c+1:]

	cmd := mapReduceCmd{
		Collection: cname,
		Map:        job.Map,
		Reduce:     job.Reduce,
		Finalize:   job.Finalize,
		Out:        fixMROut(job.Out),
		Scope:      job.Scope,
		Verbose:    job.Verbose,
		Query:      op.query,
		Sort:       op.options.OrderBy,
		Limit:      limit,
	}

	if cmd.Out == nil {
		cmd.Out = bson.D{{"inline", 1}}
	}

	var doc mapReduceResult
	err = session.DB(dbname).Run(&cmd, &doc)
	if err != nil {
		return nil, err
	}
	if doc.Err != "" {
		return nil, errors.New(doc.Err)
	}

	info = &MapReduceInfo{
		InputCount:  doc.Counts.Input,
		EmitCount:   doc.Counts.Emit,
		OutputCount: doc.Counts.Output,
		Time:        doc.TimeMillis * 1e6,
	}

	if doc.Result.Kind == 0x02 {
		err = doc.Result.Unmarshal(&info.Collection)
		info.Database = dbname
	} else if doc.Result.Kind == 0x03 {
		var v struct{ Collection, Db string }
		err = doc.Result.Unmarshal(&v)
		info.Collection = v.Collection
		info.Database = v.Db
	}

	if doc.Timing != nil {
		info.VerboseTime = doc.Timing
		info.VerboseTime.Total *= 1e6
		info.VerboseTime.Map *= 1e6
		info.VerboseTime.EmitLoop *= 1e6
	}

	if err != nil {
		return nil, err
	}
	if result != nil {
		return info, doc.Results.Unmarshal(result)
	}
	return info, nil
}
func ( q * Query ) MapReduce ( job * MapReduce , result interface { } ) ( info * MapReduceInfo , err error ) { q . m . Lock ( ) session := q . session op := q . op // Copy. limit := q . limit q . m . Unlock ( ) c := strings . Index ( op . collection , " " ) if c < 0 { return nil , errors . New ( " " + op . collection ) } dbname := op . collection [ : c ] cname := op . collection [ c + 1 : ] cmd := mapReduceCmd { Collection : cname , Map : job . Map , Reduce : job . Reduce , Finalize : job . Finalize , Out : fixMROut ( job . Out ) , Scope : job . Scope , Verbose : job . Verbose , Query : op . query , Sort : op . options . OrderBy , Limit : limit , } if cmd . Out == nil { cmd . Out = bson . D { { " " , 1 } } } var doc mapReduceResult err = session . DB ( dbname ) . Run ( & cmd , & doc ) if err != nil { return nil , err } if doc . Err != " " { return nil , errors . New ( doc . Err ) } info = & MapReduceInfo { InputCount : doc . Counts . Input , EmitCount : doc . Counts . Emit , OutputCount : doc . Counts . Output , Time : doc . TimeMillis * 1e6 , } if doc . Result . Kind == 0x02 { err = doc . Result . Unmarshal ( & info . Collection ) info . Database = dbname } else if doc . Result . Kind == 0x03 { var v struct { Collection , Db string } err = doc . Result . Unmarshal ( & v ) info . Collection = v . Collection info . Database = v . Db } if doc . Timing != nil { info . VerboseTime = doc . Timing info . VerboseTime . Total *= 1e6 info . VerboseTime . Map *= 1e6 info . VerboseTime . EmitLoop *= 1e6 } if err != nil { return nil , err } if result != nil { return info , doc . Results . Unmarshal ( result ) } return info , nil }
// MapReduce executes a map/reduce job for documents covered by the query.
// That kind of job is suitable for very flexible bulk aggregation of data
// performed at the server side via Javascript functions.
//
// Results from the job may be returned as a result of the query itself
// through the result parameter in case they'll certainly fit in memory
// and in a single document.  If there's the possibility that the amount
// of data might be too large, results must be stored back in an alternative
// collection or even a separate database, by setting the Out field of the
// provided MapReduce job.  In that case, provide nil as the result parameter.
//
// These are some of the ways to set Out:
//
//     nil
//         Inline results into the result parameter.
//
//     bson.M{"replace": "mycollection"}
//         The output will be inserted into a collection which replaces any
//         existing collection with the same name.
//
//     bson.M{"merge": "mycollection"}
//         This option will merge new data into the old output collection. In
//         other words, if the same key exists in both the result set and the
//         old collection, the new key will overwrite the old one.
//
//     bson.M{"reduce": "mycollection"}
//         If documents exist for a given key in the result set and in the old
//         collection, then a reduce operation (using the specified reduce
//         function) will be performed on the two values and the result will be
//         written to the output collection. If a finalize function was
//         provided, this will be run after the reduce as well.
//
//     bson.M{...., "db": "mydb"}
//         Any of the above options can have the "db" key included for doing
//         the respective action in a separate database.
//
// The following is a trivial example which will count the number of
// occurrences of a field named n on each document in a collection, and
// will return results inline:
//
//     job := &mgo.MapReduce{
//             Map:      "function() { emit(this.n, 1) }",
//             Reduce:   "function(key, values) { return Array.sum(values) }",
//     }
//     var result []struct { Id int "_id"; Value int }
//     _, err := collection.Find(nil).MapReduce(job, &result)
//     if err != nil {
//         return err
//     }
//     for _, item := range result {
//         fmt.Println(item.Value)
//     }
//
// This function is compatible with MongoDB 1.7.4+.
//
// Relevant documentation:
//
//     http://www.mongodb.org/display/DOCS/MapReduce
//
MapReduce executes a map / reduce job for documents covered by the query . That kind of job is suitable for very flexible bulk aggregation of data performed at the server side via Javascript functions . Results from the job may be returned as a result of the query itself through the result parameter in case they ll certainly fit in memory and in a single document . If there s the possibility that the amount of data might be too large results must be stored back in an alternative collection or even a separate database by setting the Out field of the provided MapReduce job . In that case provide nil as the result parameter . These are some of the ways to set Out : nil Inline results into the result parameter . bson . M { replace : mycollection } The output will be inserted into a collection which replaces any existing collection with the same name . bson . M { merge : mycollection } This option will merge new data into the old output collection . In other words if the same key exists in both the result set and the old collection the new key will overwrite the old one . bson . M { reduce : mycollection } If documents exist for a given key in the result set and in the old collection then a reduce operation ( using the specified reduce function ) will be performed on the two values and the result will be written to the output collection . If a finalize function was provided this will be run after the reduce as well . bson . M { .... db : mydb } Any of the above options can have the db key included for doing the respective action in a separate database . The following is a trivial example which will count the number of occurrences of a field named n on each document in a collection and will return results inline : job : = &mgo . MapReduce { Map : function () { emit ( this . n 1 ) } Reduce : function ( key values ) { return Array . sum ( values ) } } var result [] struct { Id int _id ; Value int } _ err : = collection . Find ( nil ) . MapReduce ( job &result ) if err ! = nil { return err } for _ item : = range result { fmt . Println ( item . Value ) } This function is compatible with MongoDB 1 . 7 . 4 + . Relevant documentation : http : // www . mongodb . org / display / DOCS / MapReduce