2016-12-19 1 views
2

私はNode.jsでSequelizeをApollo-ServerとExpress.jsで使用しています。Apollo GraphQLでは、値をループしないようにリゾルバを設定するにはどうすればよいですか?

さらに深くなるクエリを作成するとき、GraphQLはモデルをループし、それぞれのモデルでIDを使って別のクエリを実行しています。

たとえば、私がuser(userId) > playthroughs > scoresを取得した場合、これはそのユーザーの参照を行い(問題ありません)、次にuserId(それでも大きな問題はありません)のすべてのプレイスルーを検索しますが、それぞれplaythroughIdをループし、それぞれについて完全に別のクエリを実行します。これはうんざりして非効率で、私のクエリが必要以上に長くかかる原因となります。

代わりのループ:

SELECT scoreValue 
FROM scores 
WHERE playthroughId = id 

私は本当に配列を自分でつかむと、このようにそのループをやってみたい:私はFacebookのからの参照GraphQLを使用する場合

SELECT scoreValue 
FROM scores 
WHERE playthroughId IN (...ids) 

これがまた起こりました昨年、私はそれがアポロの実装に特有のものだとは思わない。

これらのクエリを微調整して、そのようなパフォーマンスが低下することはありません。

例リゾルバ:graphqlに加えて

const resolvers = { 
    Query: { 
     user: (_, values) => User.findOne(formatQuery(values)) 
      .then(getDataValues), 
    }, 

    Playthrough: { 
     score: ({ playthroughId }) => Score.findOne(formatQuery({ playthroughId })) 
      .then(getDataValues), 
    }, 

    User: { 
     playthroughs: ({ userId }, { take }) => Playthrough.findAll(formatQuery({ userId, take, order: 'playthroughId DESC' })) 
      .then(getAllDataValues), 
    }, 
} 

答えて

0

、Facebookはまた、多くのあまり知られていないプロジェクト、dataloaderをリリースしました。

同じダニのリクエストを1つにバッチします。あなたのコードは次のようなものになります

scoreLoader = new Dataloader(keys => { 
    return Score.findAll({ where: { id: keys } }).then(() => { 
    //Map the results back so they are in the same order as keys 
    }) 
}); 


score: ({ playthroughId }) => scoreLoader.load(playthroughId).then(getDataValues) 

もちろん、各フィールドの負荷が面倒です。したがって、dataloader-sequelizeを使用すると、すべての呼び出しをassociation.get(つまりPlaythrough.getScores())にラップし、findOne/findByIdを呼び出してdataloader呼び出しを行うため、複数の呼び出しが1つにまとめられます。

あなたはsequelizeに裏打ちされたgraphql APIを構築しているので、あなたもhttps://github.com/mickhansen/graphql-sequelize/に興味があるかもしれません、grahpqlためsequelize特定のヘルパーを提供し、ボンネットの下にあなたの詳細な回答のため

+0

感謝をデータローダー-sequelizeを使用します! graphql-sequelizeにはApolloではなく参照サーバが必要ですか?また、私がdataloader-sequelizeを使用している場合、テーブルがあまりにも正しいかどうかをセットアップする必要がありますか? – Sawtaytoes

+0

はい、grahpqlの種類などのFacebookの実装を使用しています - 私はapolloが完全に異なるバージョンを作ったことに気づいていませんでした。 dataloaderを最大限に活用するには、アソシエーションを設定する必要がありますが、アソシエーションがなくても、 'findOne'への複数の呼び出しを' findAll'の1回の呼び出しにバッチすることができます –

関連する問題