Przemek Kujonewicz
Przemek Kujonewicz

Reputation: 131

Combining the results of multiple Thinking Sphinx queries into a single paginated result

Is there a simple way to combine the results of multiple Thinking Sphinx searches into a single result? All of these searches are on the same model, but the searches have distinct search terms. What I'm trying to do is combine the results so that they can all be sorted by a date column and receive proper pagination.

Say I have a Thinker class and an Idea class.

class Thinker < ActiveRecord::Base
  has_many :ideas
end

class Idea < ActiveRecord::Base
  belongs_to :thinker

  define_index do
    indexes text
    has created_at
  end
end

And say I have two thinkers, Bob, and Alice. I want to combine the following searches:

bob.ideas.search 'pancakes', :order => :created_at, :sort_mode => :desc
alice.ideas.search 'waffles', :order => :created_at, :sort_mode => :desc

...and somehow combine them so that the collection of Bob's (pancake) and Alice's (waffle) ideas are mixed together, sorted by descending created_at, and properly paginated by Thinking Sphinx. In the actual use case, I could have anywhere between 2 and 15 searches to combine in this fashion.

I know that the search method returns a ThinkingSphinx::Search < Array. I thought about manually splicing these objects together, but the fact that I'm looking for both sorting and pagination makes this a bit tricky.

Is there an elegant way to do this in Thinking Sphinx or am I not missing anything and I pretty much have to roll my own?

Upvotes: 5

Views: 1388

Answers (3)

oliviergg
oliviergg

Reputation: 303

Thinking Sphinx work with Kaminari. So you already have kaminari in your gemfile. You just have to do :

result = bob.ideas.search 'pancakes', :order => :created_at, :sort_mode => :desc
result += alice.ideas.search 'waffles', :order => :created_at, :sort_mode => :desc

Result is no longer a ThinkingSphinx::Search. It's an array

result = Kaminari.paginate_array(result)

Your can use pagination and simple sort on result

Upvotes: 4

concept47
concept47

Reputation: 31826

first_search = bob.ideas.search 'pancakes', :order => :created_at, :sort_mode => :desc
second_search = bob.ideas.search 'pancakes', :order => :created_at, :sort_mode => :desc
results = first_search.flatten + second_search.flatten

you can now sort by date like you want

sorted_results  = results.sort_by(&:date)

hope this helps

Upvotes: 1

iwasrobbed
iwasrobbed

Reputation: 46713

You can probably do this pretty easily, but you need to rewrite your queries to be more generic and search on the Idea model itself.

Idea.search 'pancakes | waffles', :with => {:thinker_id => [bob.id, alice.id]}, 
                                  :order => :created_at, 
                                  :sort_mode => :desc,
                                  :match_mode => :boolean

And your model would be:

class Idea < ActiveRecord::Base
  belongs_to :thinker

  define_index do
    indexes text
    has created_at, thinker_id
  end
end

Upvotes: 0

Related Questions