首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从sails.js / mongodb中提取公共代码

从sails.js / mongodb中提取公共代码
EN

Stack Overflow用户
提问于 2014-09-15 09:50:00
回答 1查看 305关注 0票数 0

我正在尝试在mongodb中使用sails.js,我需要一些自定义的mapReduce函数来对数据进行分组。

现在我可以通过使用waterline的native函数来实现我想要的东西,但也有一些问题。

这些函数实际上只有很小的变化,但我发现自己经常重复下面的代码:

代码语言:javascript
复制
function getSomeData() {
  // First-query
  Log.native(function(err, logCollection) {

    var mapFunction = function() {
      function dateFormatter(date) {
        return date.getFullYear() + "-" + (date.getMonth() + 1)
      }

      //! Generate Grouping Key
      emit(dateFormatter(this.emb_date), this.bad_qty)
    }

    var reduceFunction = function (key, values) {
      return Array.sum(values);
    }

    var outputControl = {
      out: {inline: 1},
      //! Filters
      query: {order_type: product}
    }

    logCollection.mapReduce(mapFunction, reduceFunction, outputControl, function (err, result) {
      if (err) { 
        callback(err); 
        return; 
      }

      var resultSet = [];

      //! post-processing
      for (var i = 0; i < result.length; i++) {
        //.....
      }

      callback(err, resultSet);
    });
  });
}

第二项查询:

代码语言:javascript
复制
function getAnotherData() {
  Log.native(function(err, logCollection) {

    var mapFunction = function() {
      //! Generate Grouping Key
      emit(dateFormatter(this.product), this.bad_qty)
    }

    var reduceFunction = function (key, values) {
      return Array.sum(values);
    }

    var outputControl = {
      out: {inline: 1},
      //! Filters
      query: {order_type: product}
    }

    logCollection.mapReduce(mapFunction, reduceFunction, outputControl, function (err, result) {
      if (err) { 
        callback(err); 
        return; 
      }

      var resultSet = [];

      //! post-processing
      for (var i = 0; i < result.length; i++) {
        //......
      }

      callback(err, resultSet);
    });
  });
}

正如您所看到的,这两个代码片段共享大量的公共代码,仅在三个位置上有差异(生成分组键、筛选器、后处理)。

因此,我非常希望提取公共部分,以使代码更简洁,但没有成功。

我首先尝试让dateFromatter是由回调提供的,而不是像下面这样的硬编码:

代码语言:javascript
复制
function dateFormatter(data) {
  return data.emb_date.getFullYear() + "-" + (data.emb_date.getMonth() + 1)
}


function getSomeData(groupingKey) {
  // First-query
  Log.native(function(err, logCollection) {

    var mapFunction = function() {
      //! Generate Grouping Key
      emit(groupingKey(this.emb_date), this.bad_qty)
    }

    var reduceFunction = function (key, values) {
      return Array.sum(values);
    }

    var outputControl = {
      out: {inline: 1},
      //! Filters
      query: {order_type: product}
    }

    logCollection.mapReduce(mapFunction, reduceFunction, outputControl, function (err, result) {
      if (err) { 
        callback(err); 
        return; 
      }

      var resultSet = [];

      //! post-processing
      for (var i = 0; i < result.length; i++) {
        //.....
      }

      callback(err, resultSet);
    });
  });
}

但如果没有任何运气,我就会犯以下错误:

代码语言:javascript
复制
 MongoError: exception: ReferenceError: groupingKey is not defined near 'emit(groupingKey(this), this.bad_qty'  (line 3)
    at Object.toError (/home/brianhsu/zh800/dashboard/node_modules/sails-mongo/node_modules/mongodb/lib/mongodb/utils.js:114:11)

如果我想减少代码中重复的部分,我该怎么办?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-18 01:53:13

最后,我发现我需要将名为“scope”的选项传递给mongodb,我想出了以下解决方案,效果很好。

代码语言:javascript
复制
exports.defineOn = function(options) {

  var model = options.model
  var groupingFunction = options.groupingFunction
  var mongoFilters = options.mongoFilters
  var customFilter = options.customFilter
  var converter = options.converter
  var sorting = options.sorting

  return function(callback) {
    model.native(function(err, collection) {
      var mapFunction = function() { emit(groupingFunction(this), this.bad_qty) }
      var reduceFunction = function(key, values) { return Array.sum(values); }
      var mapReduceOptions = {
        out: {inline: 1},
        query: mongoFilters,
        scope: {
          groupingFunction: groupingFunction, 
          mongoFilters: mongoFilters, 
          customFilter: customFilter,
          converter: converter
        }
      }

      var processCallback = function (err, result) {
        if (err) {
          callback(err);
          return;
        }

        if (sorting) {
          result.sort(sorting);
        }

        var resultSet = [];

        for (var i = 0; i < result.length; i++) {
          if (customFilter && customFilter(result[i])) {
            resultSet.push(converter(result[i]));
          } else if (!customFilter) {
            resultSet.push(converter(result[i]));
          }
        }

        callback(err, resultSet);
      }

      collection.mapReduce(mapFunction, reduceFunction, mapReduceOptions, processCallback);
    });
  }
}

用法:

代码语言:javascript
复制
function machineDetail (year, month, date, machine, callback) {

    var startDate = new Date(+year, +(month-1), +date);
    var endDate = new Date(+year, +(month-1), (+date) + 1);

    var mapReducer = MapReducer.defineOn({
      model: Log,
      groupingFunction: function(data) {
        return {date: data.emb_date, error: data.defact_id};
      },
      mongoFilters: {
        mach_id: machine,
        emb_date: {$gte: startDate, $lt: endDate}
      },
      converter: function (data) {
        return {
          name: data._id,
          value: data.value,
        };
      }
    });

    mapReducer(callback);
  }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25845210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档