简体   繁体   中英

RoR: Elasticsearch sort by mapped field

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}

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.

sort { by Player.column_names.include?(params[:sort]) ? params[:sort] : :fullname ,%w[asc desc].include?(params[:direction]) ? params[:direction] : "desc"}

将“ id”更改为“全名”应该可以。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM