ElasticSearch Rails resource_already_exists_exception 当 运行 测试时
ElasticSearch Rails resource_already_exists_exception when running tests
我正在尝试 运行 我的一项测试,它进行搜索,试图断言搜索结果中包含记录,但与此同时,我收到 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)
我的模型中有错误的映射。我使用 index
而不是 type
选项,这使得 ElasticSearch 创建了一个多重映射。自 6.4 版以来不可用(我猜)。
很高兴您找到了具体问题的根本原因。
我 运行 与 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
我在多个规范中使用了时间冻结,因此创建一个与之前规范中的对象具有相同 created_at
时间的新对象导致了 resource_already_exists_exception
错误。稍微调整时间戳以冻结每个规范解决了这个问题。
我正在尝试 运行 我的一项测试,它进行搜索,试图断言搜索结果中包含记录,但与此同时,我收到 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)
我的模型中有错误的映射。我使用 index
而不是 type
选项,这使得 ElasticSearch 创建了一个多重映射。自 6.4 版以来不可用(我猜)。
很高兴您找到了具体问题的根本原因。
我 运行 与 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
我在多个规范中使用了时间冻结,因此创建一个与之前规范中的对象具有相同 created_at
时间的新对象导致了 resource_already_exists_exception
错误。稍微调整时间戳以冻结每个规范解决了这个问题。