【问题标题】:How to fix "Illegal Argument Exception" when creating an Elasticsearch index for a Rails model?为 Rails 模型创建 Elasticsearch 索引时如何修复“非法参数异常”?
【发布时间】:2019-11-19 21:54:55
【问题描述】:

我正在尝试将 Elasticsearch 集成到我的 rails 应用程序中。当我尝试对我的模型进行导入时,问题就出现了。 视频.__elasticsearch__.import.

所以,在 Rails 控制台中,我运行了 Video.__elasticsearch__.import。我收到此错误: myflix_development 不存在可导入。使用创建索引!或 :force 选项来创建它。

然后我运行 Video.__elasticsearch__.create_index!Video.__elasticsearch__.create_index!(force: true) 并且它们都返回了相同的非法参数异常错误:

 PUT http://localhost:9200/myflix_development [status:400, request:0.027s, query:N/A]
2019-06-08 11:18:29 +0800: > {"settings":{},"mappings":{"_doc":{"properties":{}}}}
2019-06-08 11:18:29 +0800: < {"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"The mapping definition cannot be nested under a type [_doc] unless include_type_name is set to true."}],"type":"illegal_argument_exception","reason":"The mapping definition cannot be nested under a type [_doc] unless include_type_name is set to true."},"status":400}

我知道我应该在尝试导入时创建一个 elasticsearch 索引,但我遇到了这个非法参数异常,我对此感到困惑

这是我所做的设置:

1) 在我的 gemfile 中包含 gem:

gem 'elasticsearch-model'
gem 'elasticsearch-rails'

2) 包含一个初始化程序:app/config/initializers/elasticsearch.rb

Elasticsearch::Model.client =
  if Rails.env.staging? || Rails.env.production?
    Elasticsearch::Client.new url: ENV['SEARCHBOX_URL']
  elsif Rails.env.development?
    Elasticsearch::Client.new log: true
  else
    Elasticsearch::Client.new
  end

3) 在我的视频模型中包含弹性搜索

class Video < ActiveRecord::Base
  include Elasticsearch::Model
  index_name ["myflix", Rails.env].join("_")
  ...
end

4) Gemfile.lock

 elasticsearch (7.1.0)
      elasticsearch-api (= 7.1.0)
      elasticsearch-transport (= 7.1.0)
    elasticsearch-api (7.1.0)
      multi_json
    elasticsearch-model (6.0.0)
      activesupport (> 3)
      elasticsearch (> 1)
      hashie
    elasticsearch-rails (6.0.0)
    elasticsearch-transport (7.1.0)
      faraday
      multi_json

任何帮助将不胜感激!

编辑 1) 尝试在我的模型中进行手动映射

class Video < ActiveRecord::Base
    include Elasticsearch::Model

    settings index: { number_of_shards: 1 } do
    mappings dynamic: 'false' do
      indexes :title, type: 'text'
      indexes :description, type: 'text'
    end
  end
...
end

【问题讨论】:

    标签: ruby-on-rails elasticsearch


    【解决方案1】:

    您可以通过设置document_type 明确定义elasticsearch-model 传递给Elasticsearch 的文档类型。例如:

    class Video < ActiveRecord::Base
      include Elasticsearch::Model
      index_name ["myflix", Rails.env].join("_")
      document_type "video"
      ...
    end
    

    您使用的名称是任意的。只要不是_doc,就不会在v7 及更高版本中遇到此错误。

    【讨论】:

      【解决方案2】:

      根据您遇到的错误,我认为您使用的是 elasticsearch 7。类型 _doc 在您的索引查询中指定,但类型是 deprecated since es7

      您可以尝试更新您的 elasticsearch 库以匹配 es7 或按照错误消息中的建议,您可以在映射中使用参数 include_type_name

      【讨论】:

      • 是的,我使用的是 ES 7.1.0。我在我的问题中包含了我的 gemfile.lock 文件。我想有几件事我不清楚:1)_doc 类型是在您的索引查询中指定的。 - 我在哪里可以在我的索引查询中停用这种类型的_doc?我在尝试导入时没有指定任何内容。 2)您可以尝试更新您的弹性搜索库以匹配 es7 - 我直接从网站下载 ES7。不是已经更新了吗? 3)您可以在映射中使用参数include_type_name。 - 不知道该怎么做。如何手动创建映射并指定它?
      • 我实际上也将我的 ES 版本降级到了 ES6。当我尝试在 Rails 控制台中创建索引时:Video.__elasticsearch__.import 我收到此错误:Video.__elasticsearch__.create_index! Elasticsearch::Transport::Transport::Errors::BadRequest: [400] {"error":{"root_cause":[{"type":"invalid_type_name_exception","re​​ason":"mapping type name [doc] can' t 以 ''"}(下划线)],"type":"invalid_type_name_exception","re​​ason":"mapping type name [doc] 不能以 ''"(下划线)} 开头,"status":400} 我什至不确定我在哪里指定映射类型名称 [doc] 以以下划线开头。
      • 使用 ELlasticsearch 6.0.1,我查找了如何进行映射,并将代码包含在我的原始帖子中。尽管如此,我仍然得到同样的错误映射类型名称 [doc] 不能以 ''"} 开始] 很抱歉抛出了这么多额外的 cmets!这个问题真的困扰着我
      【解决方案3】:

      由于 ElasticSearch 引擎未能分析保留关键字,因此发生“非法参数异常”。 Properties 被认为是映射部分内的根字段。通过排除“_doc”关键字将请求修改如下:

      PUT {INDEX_NAME} {"settings":{},"mappings":{"properties":{}}}}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-07
        • 1970-01-01
        • 1970-01-01
        • 2023-03-17
        • 1970-01-01
        • 2019-01-30
        • 2013-12-28
        相关资源
        最近更新 更多