exAspArk / batch-loader

:zap: Powerful tool for avoiding N+1 DB or HTTP queries
https://engineering.universe.com/batching-a-powerful-way-to-solve-n-1-queries-every-rubyist-should-know-24e20c6e7b94
MIT License
1.04k stars 52 forks source link

Searchkick(elasticsearch) Object Associations #63

Closed xgrei closed 4 years ago

xgrei commented 4 years ago

I use Searchkick gem in my project and I got a post list from Graphql, then I got N+1 problem.

# demo_schema.rb
class DemoSchema < GraphQL::Schema
  mutation ::Types::MutationType
  query ::Queries::QueryType
  use BatchLoader::GraphQL
end

# post_type.rb
module Types
  class PostType < BaseObject
    field :id, String, null: false
    field :title, String, null: false
    field :images, [Types::ImageType], null: true

    def images
      # object's class is Searchkick::HashWrapper
      BatchLoader::GraphQL.for(object.id).batch(default_value: []) do |post_ids, loader|
         Image.where(post_id: post_ids).each { |i| loader.call(i.post_id, i) }
      end
    end
  end
end

its work well in console:

SELECT `images`.* FROM `images` WHERE `images`.`post_id` IN (92, 91, 79, 56, 17, 16);

but images is null in result:

{
  "data": {
    "posts": {
      "records": [
        {
          "id": 92,
          "title": "Inkscape 1.0 Release Candidate",
          "images": []
        },
        {
          "id": 91,
          "title": "Saving Money on International Payments as a Remote Freelancer",
          "images": []
        },
        {
          "id": 79,
          "title": "Remembering Conway",
          "images": []
        },
        ...
       ]
     }
   }
 }

How to fix the problem with Graphql & Searchkick? Thanks.

exAspArk commented 4 years ago

Hey @xgrei,

It seems like images should return an array. Calling loader.call(i.post_id, i) will return a single image by a post_id.

You probably need to try https://github.com/exAspArk/batch-loader#loading-multiple-items to collect an array of images per post_id. E.g.:

loader.call(i.post_id) { |memo| memo << i }
ghost commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.