为什么LoopBack中的这个嵌套关系会返回重复的结果?

Cha*_*ser 7 loopbackjs

当我查询包含嵌套模型时 - 例如GET /api/Widgets/1?filter={include: {"foos": "bars"}}- 我foos在结果中得到重复.我认为这是由于LEFT JOIN或类似的东西,因为我正在使用MySQL,但是当我在loopback:connector:mysql调试模式下运行LoopBack时,我可以看到初始小部件的查询运行一次,但是查询foo运行两次,bar的查询运行两次.为什么会出现这种情况,我可以改变什么(我的模型,我的代码或我的期望)?

楷模:

{
  "name": "Widget",
  ...
  "relations": {
    "foos": {
      "type": "hasMany",
      "model": "Foo",
      "foreignKey": "widgetId"
    }
  }
}

{
  "name": "Foo",
  ...
  "relations": {
    "bars": {
      "type": "hasMany",
      "model": "Bar",
      "foreignKey": "fooId"
    },
    "widget": {
      "type": "belongsTo",
      "model": "Widget",
      "foreignKey": ""
    }
  }
}

{
  "name": "Bar"
  ...
  "relations": {
    "foo": {
      "type": "belongsTo",
      "model": "Foo",
      "foreignKey": ""
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

{
  id: 1
  foos: [
    {
      id: 2,
      bars: [
        {
          id: 3
        }
      ]
    },
    {
      id: 2,
      bars: [
        {
          id: 3
        }
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

期待:

{
  id: 1
  foos: [
    {
      id: 2,
      bars: [
        {
          id: 3
        }
      ]
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

这是我认为为此请求运行的释义SQL:

SELECT `...` FROM `Widget` WHERE `id`=1 ORDER BY `id` LIMIT 1
SELECT `...` FROM `Foo` WHERE `widget_id` IN (1) ORDER BY `id`
SELECT `...` FROM `Foo` WHERE `widget_id` IN (1) ORDER BY `id`
SELECT `...` FROM `Bar` WHERE `foo_id` IN (2) ORDER BY `id`
SELECT `...` FROM `Bar` WHERE `foo_id` IN (2) ORDER BY `id`
Run Code Online (Sandbox Code Playgroud)

我正在使用Loopback 3.x.

更新:虽然GET /api/Widgets/1?filter={include: {"foos": "bars"}}展示此行为的请求,服务器端执行Widgets.findById(id, {include: {"foos": "bars"}})完美.所以,目前我将创建一个远程方法来执行此操作,并可能使用LoopBack提交错误报告.

Cha*_*ser 2

我正在使用这个 mixin将查询限制limit为定义值的最大值。当include出现在查询中时,mixin 还会对包含的范围设置限制,如下所示:

"include": {"foo":"bar","scope":{"limit":1}}

似乎 mixin 假设所有作为对象的包含都将以 的形式编写{"relation":"foo", "scope":{"include:"bars"}},因此包含被添加了两次。

无论如何,我编写了这个简单的 mixin 来限制结果的最大数量,除非指定并停止使用上面链接的结果:

常见/模型/model.json:

"mixins": {
    "ResultsetLimit": {
        "limit": 100
    }
}
Run Code Online (Sandbox Code Playgroud)

常见/mixins/resultset-limit.js:

const _ = require('lodash');

module.exports = (Model, options) => {

    /**
     * Modify incoming query to apply appropriate limit filters.
     */
    Model.beforeRemote('**', (ctx, unused, next) => {

        // Get the limit from the request, defaulting to the max limit.
        const request_limit = _.toNumber(_.get(ctx, 'args.filter.limit', options.limit));

        // Set the limit.
        _.set(ctx, 'args.filter.limit', request_limit);

        next();

    });

};
Run Code Online (Sandbox Code Playgroud)