Reputation: 1452
I have Player and Player have fullname from Profil. I use elasticsearch on Player. I need default sort by fullname. How can I set it? My code from Player class file:
......
mapping do
indexes :id, type: 'integer'
indexes :fullname, boost: 10
indexes :name
indexes :surname
indexes :position_name
indexes :info
indexes :club_id, type: 'integer'
indexes :club_name
end
def self.search(params)
tire.search(load: true, page: params[:page], per_page: 20) do
query do
boolean do
if params[:query].present?
must { string params[:query], default_operator: "AND" }
else
must {string '*'}
end
must { term :position_id, params[:position_id]} if params[:position_id].present?
must { term :club_id, params[:club_id]} if params[:club_id].present?
end
end
# filter :term, user_id: params[:user_id] if params[:user_id].present?
# sort { by Item.column_names.include?(params[:sort]) ? params[:sort] : "created_at", %w[asc desc].include?(params[:direction]) ? params[:direction] : "desc" } if params[:query].blank?
sort { by Player.column_names.include?(params[:sort]) ? params[:sort] : :id ,%w[asc desc].include?(params[:direction]) ? params[:direction] : "desc"}
facet "positions" do
terms :position_id
end
facet "clubs" do
terms :club_id
end
# raise to_curl
end
end
def to_indexed_json
to_json(methods: [:fullname, :name, :surname, :position_name, :club_name])
end
def fullname
self.profil.fullname
end
......
If I changed :id to :fullname in sort I have this error:
500 : {"error":"SearchPhaseExecutionException[Failed to execute phase [query], total failure; shardFailures {[DBgvi6JiQAi0FTwhonq8Ag][players][0]: QueryPhaseExecutionException[[players][0]: query[ConstantScore(NotDeleted(cache(_type:player)))],from[0],size[20],sort[<custom:\"fullname\": org.elasticsearch.index.field.data.strings.StringFieldDataType$1@33a626ac>!]: Query Failed [Failed to execute main query]]; nested: IOException[Can't sort on string types with more than one value per doc, or more than one token per field]; }{[DBgvi6JiQAi0FTwhonq8Ag][players][4]: QueryPhaseExecutionException[[players][4]: query[ConstantScore(NotDeleted(cache(_type:player)))],from[0],size[20],sort[<custom:\"fullname\": org.elasticsearch.index.field.data.strings.StringFieldDataType$1@3274eb8a>!]: Query Failed [Failed to execute main query]]; nested: IOException[Can't sort on string types with more than one value per doc, or more than one token per field]; }]","status":500}
Upvotes: 2
Views: 1750
Reputation: 2210
I got it! After dumb amounts of research I found this article here. The first answer mentions:
The field user by default gets analyzed and broken down into one or more tokens. If it gets broken down into more than one token, then you can't really sort on it. If you want to sort on it, you either need to set it i(in the mappings) as not analyzed
In your situation, all you would need to do is:
mapping do
indexes :id, type: 'integer'
indexes :fullname, :index => 'not_analyzed'
indexes :name
indexes :surname
indexes :position_name
indexes :info
indexes :club_id, type: 'integer'
indexes :club_name
end
And it should work.
Upvotes: 7
Reputation: 379
sort { by Player.column_names.include?(params[:sort]) ? params[:sort] : :fullname ,%w[asc desc].include?(params[:direction]) ? params[:direction] : "desc"}
Changing 'id' to 'fullname' should work.
Upvotes: 0