RoR:Elasticsearch按映射字段排序

时间:2012-08-07 09:59:25

标签: ruby-on-rails elasticsearch tire

我有玩家和玩家有来自Profil的全名。我在Player上使用elasticsearch。我需要按姓名默认排序。我怎么设置它?我的代码来自Player类文件:

   ......
  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
......

如果我改变了:id to:fullname in sort我有这个错误:

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}

2 个答案:

答案 0 :(得分:7)

我明白了!经过大量的研究后,我发现this article here。第一个答案提到:

  

默认情况下,字段用户会被分析并分解为一个或多个令牌。如果它被分解为多个令牌,那么你无法真正对它进行排序。如果你想对它进行排序,你需要将其设置为i(在映射中)为未分析

在您的情况下,您需要做的就是:

 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

它应该有用。

答案 1 :(得分:0)

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

将'id'更改为'fullname'应该有效。