8

我将如何在 Loopback 模型中使用聚合函数?如果我有一个由 mysql 数据库支持的模型,我是否可以让 Model1 与 Model2 具有 hasMany 关系(具有给定的数字属性),并且在 Model1 中有一个属性可以从 Model2 中获取该字段的 SUM?

    {
        “模型1”:{
            “关系”:{
                “模型2s”:{
                    "type": "hasMany",
                    “模型”:“模型 2”,
                    "foreignKey": "model1Id"
                }
            },
            “特性” : {
                “全部的” : {
                    “类型”:“数字”
                    [Model2‘金额’字段的总和]
                }
            }
        },
        “模型2”:{
            “关系”:{
                “模型1s”:{
                    “类型”:“属于”,
                    “模型”:“模型 1”,
                    "foreignKey": "model1Id"
                }
            },
            “特性” : {
                “数量” : {
                    “类型”:“数字”
                }
            }
        }
    }

在另一件事上,将条件放入模型中的正确方法是什么,以便 getter 返回的值取决于某个表达式?我想从关系中返回一个值(如果存在),否则返回主模型上存在的值。

我试过这个(伪代码):

    module.exports = 功能(MyModel){
        MyModel.on('附加', function() {
            var app = MyModel.app;

            MyModel.getter['total'] = function() {
                返回(this.model1Id?this.model1.total:this.total);
            };
        });

    };

但是,我最终得到一个RangeError: Maximum call stack size exceeded错误(类似于这个问题中提到的)。我假设这是因为它一遍又一遍地递归调用 getter,但我不确定解决问题的方法。

提前致谢...

4

5 回答 5

13

这可以通过 Loopback 的操作钩子来完成。

Model1.observe('loaded', function (ctx, next) {
  if (ctx.instance) {
    var sum = 0;

    Model1.app.models.Model2.find({
      where: {
        model1Id: ctx.instance.id
      },
      fields: {
        givenNumericProperty: true
      }
    }, function (err, model2s) {
      if (err) return next(err);

      if (model2s.length) {
        model2s.forEach(function (model2) {
          sum += model2.givenNumericProperty;
        });

        ctx.instance.calculatedProperty = sum;
      }

      return next();
    });

  } else {
    return next();
  }
});
于 2015-08-29T12:03:10.663 回答
6

AFAIK 环回目前不支持聚合函数/属性。请打开一个 github 问题以将此作为功能请求进行跟踪。

请注意,访问相关模型的数据是异步操作,因此不可能可靠地实现属性(getter 函数)来返回聚合结果。

这是一个展示如何正确实现计算的模型total

MyModel.prototype.getTotal = function(cb) {
  if (!this.model1Id) {
    // No related model, return the total from this model.
    return cb(null, this.total);
  }

  // Fetch the related model and return its total
  this.model1(function(err, model1) {
    if (err)
      cb(err);
    else
      cb(null, model1.total);
  });
}

在另一件事上,将条件放入模型中的正确方法是什么,以便 getter 返回的值取决于某个表达式?我最终得到一个RangeError: Maximum call stack size exceeded错误

正如我在您链接到的答案中解释的那样,this.total调用您的自定义 getter 函数,该函数依次调用this.total等等。

解决方案是从内部数据对象中读取值:

MyModel.getter['total'] = function() {
   return this.__data.total;
};
于 2014-08-22T07:44:36.923 回答
3

您可以尝试 3rd 方插件:

1) 用于聚合的环回连接器: https ://github.com/benkroeger/loopback-connector-aggregate

2)计算/计算属性的环回混合(仅在创建新模型实例时有效): https ://github.com/fullcube/loopback-ds-calculated-mixin https://github.com/fullcube/loopback-ds-计算混合

3) Loopback mixin for change tracking (launches on every update): https://github.com/fullcube/loopback-ds-changed-mixin

4) If you need a stats - here is another mixin: https://github.com/jonathan-casarrubias/loopback-stats-mixin

5) You can count related models: https://github.com/exromany/loopback-counts-mixin

6) You can automaticly denormalize and save related data and choose what fields will be stored (useful for caching): https://github.com/jbmarchetti/loopback-denormalize

7) If you need a computed properties for field mapping during import: https://github.com/jonathan-casarrubias/loopback-import-mixin

于 2016-05-22T06:51:21.893 回答
0

我不确定你是否找到了你要找的东西,但我正在寻找类似的功能,但找不到。在询问堆栈溢出后,我最终编写了自己的插件,该链接对此进行了详细说明。

于 2015-03-04T17:34:33.650 回答
0

With loopback 3 you can do this:

  Report.observe("loaded", (ctx, next) => {  
    ctx.data.SOMEKEY = 'SOME VALUE'
    next();

});

于 2019-10-04T02:24:19.183 回答