当我查询包含嵌套模型时 - 例如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提交错误报告.
我正在使用这个 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)
| 归档时间: |
|
| 查看次数: |
1260 次 |
| 最近记录: |