title: Custom fields in MongoDB query result
body: <p>After being so used to SQL, I have came across this problem with mongoDB.
  First, I am using mongoose.</p>
  
  <p>Now, the problem. I have a collection named <code>User</code>. </p>
  
  <pre><code>var UserSchema = new Schema ({
      id : ObjectId,
      name : {type : String, trim : true, required : true},
      email: {type:String, trim:true, required: true, index: { unique: true }},
      password: {type:String, required: true, set: passwordToMD5},
      age: {type:Number, min: 18, required: true, default: 18},
      gender: {type: Number, default:0, required: true},
  
      height: {type: Number, default:180, min: 140, max: 220},
      _eye_color: {type: ObjectId, default: null},
      location: {
              lon: {type: Number, default: 0},
              lat: {type: Number, default: 0}
      },
      status: {type:Number, required: true, default:0}
      },{
          toObject: { virtuals: true },
          toJSON: { virtuals: true },
          collection:"user"});
  </code></pre>
  
  <p>Now I need to select all users from this collection and sort them by special attribude (say "rank"). This rank is calculated with certain logic depending of their distance from a point, age compared with given age, etc...</p>
  
  <p>So now I was wondering how to select this rank and then use it in sorting? I have tried to use virtuals, they are handy to count additional info, but unfortunately, it is not possible to sort the <code>find()</code> results by a virtual field. 
  Of course I can calculate this rank in a virtual, then select all records, and after that, in callback, do some javascript. But in this case, as I select all the users then sort and then limit, the javascript part might take too long...
  I was thinking to use <strong>mapreduce</strong>, but I am not sure it will do what I want.
  Can someone give me a hint if my task is possible to do in <strong>mongoDB/mongoose</strong>?</p>
  
  <p><strong>EDIT 1</strong></p>
  
  <p>I have also tried to use aggregation framework, and at first it seemed to be the best solution with the <code>$project</code> ability. But then, when I needed to do rank calculations, I found out that aggregation does not support a lot of mathematical functions like <code>sin</code>, <code>cos</code> and <code>sqrt</code>. And also it was impossible to use pre-defined usual javascript functions in projection. I mean,the function got called, but I was not able to pass current record fields to it.</p>
  
  <pre><code>{$project: {
    distance_from_user: mUtils.getDistance(point, this.location)
  }
  </code></pre>
  
  <p>Inside function the second attr was "undefined".</p>
  
  <p>So I guess it is impossible to do my rank calculations with aggregation framework.</p>
  
  <p><strong>EDIT 2</strong>
  Ok, I know everyone tells me not to use mapreduce as it is not good for realtime queries, but as I cannot use aggregation, I think I'll try mapreduce. So Let's say I have this map reduce.</p>
  
  <pre><code>function map() {
              emit(1, // Or put a GROUP BY key here
                  {name: this.name, // the field you want stats for
                      age: this.age,
                      lat: this.location.lat,
                      lon: this.location.lon,
                      distance:0,
                      rank:0
  
                  });
          }
  
          function reduce(key, values) {
  
  
              return val;
          }
  
          function finalize(key, value){
  
              return value;
          }
  
  
          var command = {'mapreduce': "user", 'map': map.toString(), 'reduce': reduce.toString(), query:{$and: [{gender: user_params.gender}, {_id: {$ne: current_user_id}}]}, 'out': {inline:1}};
  
          mongoose.connection.db.executeDbCommand(command, function(error, result){
              if(error) {
                  log(error);
                  return;
              }
              log(result);
              return;
          });
  </code></pre>
  
  <p>What should I write in reduce (or maybe change map) to calculate rank for every user?</p>