2017-02-01 8 views
6

ネストされたモデルを含めるようにクエリするとGET /api/Widgets/1?filter={include: {"foos": "bars"}} - 私の結果にはfoosが重複しています。私はこれがLEFT JOINなどのものだと思っていましたが、MySQLを使用しているので、loopback:connector:mysqlデバッグモードでLoopBackを実行すると、最初のウィジェットのクエリは一度実行されますが、 fooは2回実行され、barのクエリは2回実行されます。なぜこの現象が発生していますか(私のモデル、私のコード、または私の期待)を変更することはできますか?LoopBackでこのネストされた関係が重複した結果を返すのはなぜですか?

モデル:期待

{ 
    id: 1 
    foos: [ 
    { 
     id: 2, 
     bars: [ 
     { 
      id: 3 
     } 
     ] 
    }, 
    { 
     id: 2, 
     bars: [ 
     { 
      id: 3 
     } 
     ] 
    } 
    ] 
} 

{ 
    "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": "" 
    } 
    } 
} 

結果。これは、SQLを言い換えている

{ 
    id: 1 
    foos: [ 
    { 
     id: 2, 
     bars: [ 
     { 
      id: 3 
     } 
     ] 
    } 
    ] 
} 

私は、この要求のためのものの実行を参照してください。

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` 

私はループバック3.xを使用しています。

更新:GET /api/Widgets/1?filter={include: {"foos": "bars"}}展示この動作、完全にWidgets.findById(id, {include: {"foos": "bars"}})作品のサーバ側の実行の要求をしながら。ですから、現時点ではこれを行うリモートメソッドを作成し、おそらくLoopBackでバグレポートを提出します。

+1

サーバー側の実行で正常に動作し、API呼び出しで重複が発生する場合は、[Loopback routes](https://loopback.io/doc/en/lb3/Routing)に問題がある可能性があります。 html);二重ルートまたはいくつかのネストされたルートがこの問題を引き起こす可能性があります。 –

+0

あなたはそれを解決しますか? – Casy

+0

似たような問題が発生している場合は、私の答え、@Casyを参照してください。ありがとうChristos、それは私がそれを整理するのに役立ちました。 –

答えて

0

私は定義された時に最大にクエリのlimitを制限this mixinを使用していました値。 includeがクエリ中に存在する場合、ミックスインはまた、そうなどを含むの範囲に制限を設定:

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

は、ミックスインはすべてのオブジェクトが{"relation":"foo", "scope":{"include:"bars"}}の形式で記述されるていることを含んでいると仮定した思えます。

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 
    } 
    } 
} 

UPDATE:

これは私が第二(または第三)を呼び出す方法ですレベルの関係:

/api/Widgets/1?filter={include: [{"relation":"foo", "scope":{"include:"bars"}}]} 
+0

これは違いはありません。デフォルトのforeignKeyは、行が空であるか省略されたかにかかわらず、 'relationName + 'Id''として計算されます。 –

+0

が私の答えを更新しました。第3レベルの関係をどのように呼び出すかを追加しました。 –

+1

それは参考になります、Mark。この問題を引き起こしたミックスインは、すべてのマルチレベル関係がこのように定義されていると仮定していたと思います。 –

関連する問題