AvgAccumulator.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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. //DEPENDENCIES
  18. var Value = require("../Value");
  19. klass.create = function create() {
  20. return new AvgAccumulator();
  21. };
  22. proto.getFactory = function getFactory(){
  23. return klass; // using the ctor rather than a separate .create() method
  24. };
  25. proto.processInternal = function processInternal(input, merging) {
  26. if (!merging) {
  27. if (typeof input !== "number") {
  28. return;
  29. }
  30. this.total += input;
  31. this.count += 1;
  32. } else {
  33. Value.verifyDocument(input);
  34. this.total += input[this.subTotalName];
  35. this.count += input[this.countName];
  36. }
  37. };
  38. proto.getValue = function getValue(toBeMerged){
  39. if (!toBeMerged) {
  40. if (this.totalIsANumber && this.count > 0) {
  41. return this.total / this.count;
  42. } else if (this.count === 0) {
  43. return 0;
  44. } else {
  45. throw new Error("$sum resulted in a non-numeric type");
  46. }
  47. } else {
  48. return {
  49. subTotalName : this.total,
  50. countName : this.count
  51. };
  52. }
  53. };
  54. proto.reset = function reset() {
  55. this.total = 0;
  56. this.count = 0;
  57. };
  58. proto.getOpName = function getOpName(){
  59. return "$avg";
  60. };