AvgAccumulator.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. "use strict";
  2. /**
  3. * A class for constructing accumulators to calculate avg.
  4. * @class AvgAccumulator
  5. * @namespace mungedb-aggregate.pipeline.accumulators
  6. * @module mungedb-aggregate
  7. * @constructor
  8. **/
  9. var AvgAccumulator = module.exports = function AvgAccumulator(){
  10. this.subTotalName = "subTotal";
  11. this.countName = "count";
  12. this.totalIsANumber = true;
  13. this.total = 0;
  14. this.count = 0;
  15. base.call(this);
  16. }, klass = AvgAccumulator, Accumulator = require("./Accumulator"), base = Accumulator, proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
  17. // NOTE: Skipping the create function, using the constructor instead
  18. // DEPENDENCIES
  19. var Value = require("../Value");
  20. // MEMBER FUNCTIONS
  21. proto.processInternal = function processInternal(input, merging) {
  22. if (!merging) {
  23. if (typeof input !== "number") {
  24. return;
  25. }
  26. this.total += input;
  27. this.count += 1;
  28. } else {
  29. Value.verifyDocument(input);
  30. this.total += input[this.subTotalName];
  31. this.count += input[this.countName];
  32. }
  33. };
  34. proto.getValue = function getValue(toBeMerged){
  35. if (!toBeMerged) {
  36. if (this.totalIsANumber && this.count > 0) {
  37. return this.total / this.count;
  38. } else if (this.count === 0) {
  39. return 0;
  40. } else {
  41. throw new Error("$sum resulted in a non-numeric type");
  42. }
  43. } else {
  44. var ret = {};
  45. ret[this.subTotalName] = this.total;
  46. ret[this.countName] = this.count;
  47. return ret;
  48. }
  49. };
  50. proto.reset = function reset() {
  51. this.total = 0;
  52. this.count = 0;
  53. };
  54. proto.getOpName = function getOpName(){
  55. return "$avg";
  56. };