Elasticsearch-rails: Sort option is ignored with kaminari

Created on 1 Oct 2014  路  14Comments  路  Source: elastic/elasticsearch-rails

Hello

I'm trying to use ES sort option like

 @results = self.search( { 
                  :query => {
                        ....
                      } 
                   } ) , 
                  :sort => [
                    { :created_at => :desc }
                  ] } )

and paginate results like this with _Kaminari_ gem

@results.page( page ).per(50).records

And appears that :sort option doesn't affect results at all. I'm also using _Mongoid_. Any suggestions?

Thanks.

stale

Most helpful comment

I have the same problem running Mongoid v3. The to_a suggestion didn't work.

All 14 comments

I've added an integration test in 354b25a, and it works for me for ActiveRecord... Can you try a similar test/code with Mongoid? Also, might be different on ActiveModel/Mongoid versions 3 and 4...

Thanks for such a quick reply. So far, I think the order gets ruined during .records operation which queries mongo with [$in] operator. I'll let you know when I have more certain results about this.

Thanks again, you rock!

Small update on this, looks like that adding @results.page( page ).per(50).records.to_a fixes ordering issue.

@DmitriySalko Hmm, to_a shouldn't "fix" anything, since it's called for any each, first you do on the collection.

I have the same problem running Mongoid v3. The to_a suggestion didn't work.

I have _mongoid (4.0.0)_ and to_a seems like a workaround, but I still want to do more tests to be sure.

I'm seeing the same behavior with mongoid-4.0.0, kaminari-0.15.1, and elasticsearch-[rails|model]-0.1.6.

Returning the results as @results.page(page).per(10).records ignores the sorting, whereas @results.page(page).per(10).records.to_a correctly sorts the result.

We just hit this issue with Mongoid, Kaminari and es-rails - in (re)tire it appears that the preservation of search result ordering is done on the (equivalent) records call if the records are loaded (see https://github.com/karmi/retire/blob/master/lib/tire/results/collection.rb#L149), but in elasticsearch-rails/model this isn't the case.

The to_a is important -- when you see the code of the adapters, _that_ is the place where the re-ordering of records (based on order of _results_) is being done.

@JamesHarrison Can you be more specific? I'm getting lost in the discussion :)

Specifically, Kaminari (and I assume other paginators) assume you're passing in the records object, along with associated metadata about number of pages of results, total max results, etc. While you can pass Kaminari a raw array it's not the recommended way to use it. Having to call to_a in order to get the results back sorted means Kaminari doesn't get sorted results, because it doesn't call to_a as it can just enumerate results directly off the returned records.

In Tire, if you called .results you got a sorted set of results without any further calls. Monkeypatching es-rails to do the same doesn't appear to cause any issues, and I'm not sure why the sorting code should be isolated and only called on to_a in es-rails

any update on this ?

Reproduced on PostgreSQL. to_a did not resolve.

I had the same issue with MySQL. I was applying a random score function and it was being ignored. I added to_a and then it worked.

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

Was this page helpful?
0 / 5 - 0 ratings