【问题标题】:ElasticSearch Rails resource_already_exists_exception when running tests运行测试时的 ElasticSearch Rails resource_already_exists_exception
【发布时间】:2019-03-04 21:07:17
【问题描述】:

我正在尝试运行我的一项测试,该测试进行搜索,试图断言在搜索结果中包含记录,但与此同时,我收到 Elasticsearch::Transport::Transport::Errors::BadRequest 错误:

SearchTest#test_simple_test_returns_product:
Elasticsearch::Transport::Transport::Errors::BadRequest: [400] 

{
  "error":{
    "root_cause":[
      {
        "type":"resource_already_exists_exception",
        "reason":"index [app_application_test_products/FTt1YC6eQrCw2XwJuqjmDw] already exists",
        "index_uuid":"FTt1YC6eQrCw2XwJuqjmDw",
        "index":"app_application_test_products"
      }
    ],
    "type":"resource_already_exists_exception",
    "reason":"index [app_application_test_products/FTt1YC6eQrCw2XwJuqjmDw] already exists",
    "index_uuid":"FTt1YC6eQrCw2XwJuqjmDw",
    "index":"app_application_test_products"
  },
  "status":400
}

当我在开发中执行搜索时,它按预期工作,但在测试中抛出此类错误,在测试中我添加了导入和索引刷新,仅此而已:

class SearchTest < ActiveSupport::TestCase
  setup do
    Product.import force: true
    Product.__elasticsearch__.refresh_index!
  end

  test "simple test returns product" do
    product = products(:one)
    I18n.locale = product.market.lang
    search = Search.new(
      category: product.category.custom_slug,
      page: 1,
      market_id: product.market_id,
      status: "active",
      seed: Date.today.to_time.to_i
    )
    assert_includes search.results.records, products(:one)
    assert_includes search.results.records, products(:two)
    assert_not_includes search.results.records, products(:three)
  end
end

感谢任何帮助,以及改进代码的任何提示。

我正在使用:

# Gemfile
gem 'minitest', '5.10.1'

# Gemfile.lock
elasticsearch (6.1.0)
elasticsearch-model (6.0.0)
elasticsearch-rails (6.0.0)
minitest (= 5.10.1)

【问题讨论】:

    标签: ruby-on-rails ruby elasticsearch minitest elasticsearch-rails


    【解决方案1】:

    很高兴您找到了具体问题的根本原因。

    我在使用 ruby​​-on-rails gem for elasticsearch 时遇到了类似的问题。虽然映射都很好,但我确实收到了完全相同的错误消息。在这里留下我的答案,以便其他来到这里的人可以获得更多帮助。

    经过多次尝试和错误,最终弄清楚原因是它在创建索引时超时。

    如果您将客户端超时更改为 60 秒(它在 30 秒内失败),它能够成功创建索引而不会导致此间歇性错误。

    connection_hash = {
          hosts: [ "localhost:9220" ]
          reload_connections: true
          adapter: :httpclient
          retry_on_failure: 2
          request_timeout: 60
    }
    
    es_connection_client = Elasticsearch::Client.new(connection_hash)
    

    另外,发现这个问题是相关的,并在类似的答案后关闭。 https://github.com/ankane/searchkick/issues/843#issuecomment-384136164

    【讨论】:

    • 谢谢,这让我发疯了!
    【解决方案2】:

    我在多个规范中使用时间冻结,因此创建一个与之前规范中的对象具有相同 created_at 时间的新对象会导致 resource_already_exists_exception 错误。稍微调整时间戳以冻结每个规范解决了这个问题。

    【讨论】:

      【解决方案3】:

      我的模型中有错误的映射。我使用的是index,而不是使用type 选项,这使得ElasticSearch 创建了一个多重映射。自 6.4 版以来不可用(我猜)。

      【讨论】:

        猜你喜欢
        • 2021-01-02
        • 1970-01-01
        • 2022-07-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多