简体   繁体   中英

Sort on field with different locale with ElasticSearch

In project, there was a need in sorting records by one field stored in different locales. What I have: table "companies", there is no field named "name", but there is a table:

create_table "company_localizations" do |t|
  t.integer "company_id"
  t.string "locale"
  t.string "name"
  ...
end

I have index company.rb:

mapping do
  indexes :name, :type => "multi_field",
    :fields => {
       :name => {:type => "string", :index => "analyzed"},
       :name_sort => {:type => "string", :index => "not_analyzed"}
    }
end

I need to make sort on this field. I'm using ElasticSearch and Tire gem.

In Tire, use

sort { by "name.name_sort" }

in your case. The name_ prefix in your example is not needed -- without it, you can refer to your field as name.sort .

See https://github.com/karmi/tire/blob/master/test/integration/sort_test.rb and other integration tests for more info.

I've got a really strange action of Elastic, but it didn't sort on multi_filed type. There was a problem that in an app it could be russian symbols in english locale and english symbols in russian locale field in the database, so it didn't sort with the multi_filed type... I've successed with changing the multi_filed to nested in such way:

settings :analysis => {
  :analyzer => {
    :sort_analyzer => {
      "tokenizer" => "keyword",
      "filter" => ["lowercase"]
    }
  }
}

mapping do
  indexes :name do
    indexes :name
    indexes :name_sort, :type => "string", :analyzer => "sort_analyzer"
  end
...
end


def to_indexed_json
 {
    ...
    :name => {
      :name => all_localizations(:name).join(" "),
      :name_sort => all_localizations(:name).join(" ").mb_chars.strip.to_s
    },
    ...
  }
end

That fixes the problem....

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