toptal / chewy

High-level Elasticsearch Ruby framework based on the official elasticsearch-ruby client
MIT License
1.88k stars 366 forks source link

Mapping fields is not working after upgrade from version 5 #853

Open dbachinin opened 2 years ago

dbachinin commented 2 years ago

Expected behavior

After run rails chewy:reset command mapping fields is succeffuled. Request result seen like is this:

[{"attributes"=>
   {"id"=>"3",
    "fullname"=>"Hyg Hhv",
    "name_autocomplete"=>{"input"=>["Hyg", "Hhv", "Hyg Hhv", "Hhv Hyg"], "contexts"=>{"location_id"=>[1]}},
    "firstname"=>"Hyg",
    "lastname"=>"Hhv",
    "email"=>"asd@asd.com",
    "phone"=>"0001354216",
    "staff"=>0,
    "status"=>1,
    "priority"=>"cold",
    "locations"=>[1],
    "company"=>1,
    "del"=>"true",
    "idle_days_date"=>"2020-11-06T00:00:00.000Z",
    "register_date"=>"2016-07-06T11:43:49.000Z",
    "_score"=>0.0,
    "_explanation"=>nil},
  "_data"=>
   {"_index"=>"customers",
    "_type"=>"customer",
    "_id"=>"3",
    "_score"=>0.0,
    "_source"=>
     {"fullname"=>"Hyg Hhv",
      "name_autocomplete"=>{"input"=>["Hyg", "Hhv", "Hyg Hhv", "Hhv Hyg"], "contexts"=>{"location_id"=>[1]}},
      "firstname"=>"Hyg",
      "lastname"=>"Hhv",
      "email"=>"asd@asd.com",
      "phone"=>"0001354216",
      "staff"=>0,
      "status"=>1,
      "priority"=>"cold",
      "locations"=>[1],
      "company"=>1,
      "del"=>"true",
      "idle_days_date"=>"2020-11-06T00:00:00.000Z",
      "register_date"=>"2016-07-06T11:43:49.000Z"}}}]

Actual behavior

After run rails chewy:reset command mapping doesn't working. I don't see mapped fields. Only native model fields from database.

[{"attributes"=>
   {"id"=>3,
    "firstname"=>"Hyg",
    "lastname"=>"Hhv",
    "email"=>"asd@asd.com",
    "is_deleted"=>true,
    "created_at"=>"2016-07-06T11:43:49.000Z",
    "updated_at"=>"2016-07-06T16:46:28.000Z",
    "phone"=>"(000) 135-4216",
    "location_id"=>1,
    "alt_phone"=>"",
    "address_line_1"=>"",
    "address_line_2"=>"",
    "city"=>"",
    "state"=>"Florida",
    "zip_code"=>"",
    "country"=>"US",
    "sex"=>"",
    "date_of_birth"=>"2016-07-06",
    "updated_by_user_id"=>1,
    "status"=>"guest",
    "priority"=>"cold",
    "user_id"=>nil,
    "waiver"=>nil,
    "source"=>"undefined",
    "idle_days"=>615,
    "phone_status"=>nil,
    "des_subscription_status"=>"active",
    "phone_subscription_status"=>"phone_active",
    "member_id"=>nil,
    "idle_days_date"=>"2020-11-06T00:00:00.000Z",
    "sync_options"=>nil,
    "club_ready_id"=>nil,
    "_score"=>1.0,
    "_explanation"=>nil},
  "_data"=>
   {"_index"=>"customers_1657834608458",
    "_type"=>"_doc",
    "_id"=>"3",
    "_score"=>1.0,
    "_source"=>
     {"id"=>3,
      "firstname"=>"Hyg",
      "lastname"=>"Hhv",
      "email"=>"asd@asd.com",
      "is_deleted"=>true,
      "created_at"=>"2016-07-06T11:43:49.000Z",
      "updated_at"=>"2016-07-06T16:46:28.000Z",
      "phone"=>"(000) 135-4216",
      "location_id"=>1,
      "alt_phone"=>"",
      "address_line_1"=>"",
      "address_line_2"=>"",
      "city"=>"",
      "state"=>"Florida",
      "zip_code"=>"",
      "country"=>"US",
      "sex"=>"",
      "date_of_birth"=>"2016-07-06",
      "updated_by_user_id"=>1,
      "status"=>"guest",
      "priority"=>"cold",
      "user_id"=>nil,
      "waiver"=>nil,
      "source"=>"undefined",
      "idle_days"=>615,
      "phone_status"=>nil,
      "des_subscription_status"=>"active",
      "phone_subscription_status"=>"phone_active",
      "member_id"=>nil,
      "idle_days_date"=>"2020-11-06T00:00:00.000Z",
      "sync_options"=>nil,
      "club_ready_id"=>nil}}}]

Steps to reproduce the problem

I was upgrade Chewy from 5.1.0 version to 7.2.6. Applied changes from https://github.com/toptal/chewy/blob/master/migration_guide.md this migration guide. (class name index? i.e. CustomersIndex::Customer, and type name changes from string to text) And some changes I has applied 1 year ago. When migration from 5 elasticsearch to 6.8? and rails 4.2 to 5.2.

Version Information

Share here essential version information such as:

My index file is:

class CustomersIndex < Chewy::Index

  settings analysis: {
    tokenizer: {
      customngram: {
        min_gram: "2",
        type: "ngram",
        max_gram: "15"
      }
    },
    filter: {
      custom_word_delimiter: {
        type: 'word_delimiter',
        generate_word_parts: true,    # "PowerShot" => "Power" "Shot", части одного слова становятся отдельными токенами
        generate_number_parts: true,  # "500-42" => "500" "42"
        catenate_words: false,        # "wi-fi" => "wifi"
        catenate_numbers: false,      # "500-42" => "50042"
        catenate_all: false,          # "wi-fi-4000" => "wifi4000"
        split_on_case_change: true,   # "PowerShot" => "Power" "Shot"
        preserve_original: false,     # "500-42" => "500-42" "500" "42"
        split_on_numerics: true       # "j2se" => "j" "2" "se"
      },
      email: {
        type: :pattern_capture,
        preserve_original: true,
        patterns: [
          "([^@]+)",
          "(\\p{L}+)",
          "(\\d+)",
          "@(.+)",
          "([^-@]+)"
        ]
      },
      phone: {
        type:     :ngram,
        min_gram: 4,
        max_gram: 10
      },
      fullname: {
        type:     :ngram,
        min_gram: 3,
        max_gram: 10
      }
    },
    analyzer: {
      split_tokens: {
        tokenizer: :letter,
        filter: [:lowercase],
      },
      email: {
        tokenizer: :uax_url_email,
        filter: [
          :email,
          :lowercase,
          :unique
        ]
      },
      phone: {
        tokenizer: :standard,
        filter: [
          :phone
        ]
      },
      fullname: {
        tokenizer: :customngram,
        filter: [
          :lowercase
        ]
      },
      fullname_search: {
        tokenizer: :letter,
        filter: [
          :lowercase
        ]
      }
    }
  }

  index_scope Customer.where(id: 3).includes(:company, :user) do
    default_import_options batch_size: 100_000, bulk_size: 50.megabytes, refresh: false, journal: true
    field :fullname, value: -> (customer) { customer.fullname }, analyzer: :fullname
    field :name_autocomplete, {
      value: -> (customer) {
        names = [customer.firstname, customer.lastname]
        perms = []
        (1..(names.length)).each { |i| perms << names.permutation(i).to_a }
        perms = perms.map { |e| e.map { |e| e.join(' ') }} .flatten # this enables search for any order of names in string especially for multi-word names, such as Eva Maria Gonzales
        {
          input: perms,
          # output: customer.fullname,
          contexts: {
            location_id: customer.locations.ids,
          },
        }
      },
      type: "completion",
      contexts: [{
        name: :location_id,
        type: "category",
      }],
    }
    field :firstname, type: :text, index: 'analyzed'
    field :lastname, type: :text, index: 'analyzed'
    field :email, analyzer: :fullname, type: 'text', index: 'analyzed' # Elasticsearch-related options
    field :phone, value: -> (customer) { customer.phone.gsub(/[^0-9]/i, '') }
    field :staff, value: -> (customer) { customer.user ? customer.user.id : 0 }
    field :status, value: ->(customer) { customer.status_id } # custom value proc
    field :priority, value: ->(customer) { customer.priority} #{ user.badges.map(&:name) } # passing array values to index
    field :locations, value: ->(customer) { (customer.location_ids << customer.location_id).uniq }
    field :company, value: ->(customer) { customer.company.id }
    field :del, value: ->(customer) { customer.is_deleted ? 'true' : 'false' }, type: :boolean
    field :idle_days_date, type: :date, value: ->{ idle_days_date }, include_in_all: false
    field :register_date, type: :date, value: ->{ created_at }, include_in_all: false # value proc for source object context
  end
end