当我查询包含嵌套模型时 - 例如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": ""
}
}
}
结果:
{
id: 1
foos: [
{
id: 2,
bars: [
{
id: 3
}
]
},
{
id: 2,
bars: [
{
id: 3
}
]
}
]
}
期待:
{
id: 1
foos: [
{
id: 2,
bars: [
{
id: 3
}
]
}
]
}
这是我认为正在为此请求运行的释义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`
我正在使用Loopback 3.x。
更新:当GET /api/Widgets/1?filter={include: {"foos": "bars"}}
的请求出现此行为时,Widgets.findById(id, {include: {"foos": "bars"}})
的服务器端执行效果很好。所以,目前我将创建一个远程方法来执行此操作,并可能使用LoopBack提交错误报告。
答案 0 :(得分:2)
我使用的是this mixin,它将查询的limit
限制为最大值。如果查询中存在include
,则mixin还会对包含范围设置限制,如下所示:
"include": {"foo":"bar","scope":{"limit":1}}
似乎mixin假设所有包含的对象都将以{"relation":"foo", "scope":{"include:"bars"}}
的形式编写,因此包含会被添加两次。
为了它的价值,我写了这个简单的mixin来限制最大结果数,除非使用上面链接的那个指定和停止:
<强>公共/模型/ model.json:
"mixins": {
"ResultsetLimit": {
"limit": 100
}
}
<强>公共/混入/结果集-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();
});
};
答案 1 :(得分:1)
您是否尝试删除以下行?
因为默认情况下,如果未设置foreignKey
,则会将其设置为<relationName>Id
。但是,由于您将其设置为空白,因此环回不会查找要引用的任何列。因此它会获得相关模型的所有记录。
{
"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": "" // remove this
}
}
}
{
"name": "Bar"
...
"relations": {
"foo": {
"type": "belongsTo",
"model": "Foo",
"foreignKey": "" //remove this
}
}
}
更新:
这就是我称之为第二级(或第三级)的关系:
/api/Widgets/1?filter={include: [{"relation":"foo", "scope":{"include:"bars"}}]}