SearchKick:search_index.refresh如何与异步回调一起使用?
在典型的导轨控制器中,我们创建POST
模型,然后重定向到Posts_path
。 索引
操作使用搜索kick列出帖子。
# In the model
class Post < ApplicationRecord
searchkick callbacks: :async
end
# In the controller
def index
@posts = Post.search("*")
end
def create
Post.create!(post_params)
redirect_to posts_path
end
但是,由于Elasticsearch最终是一致的,因此有时重定向发生在搜索Kearchkick/Elasticsearch索引该记录之前。
搜索Kick的文档指出一个人可以使用post.search_index.refresh
等待索引赶上新记录。因此,人们可以写:
def create
Post.create!(post_params)
Post.search_index.refresh
redirect_to posts_path
end
但是,有时我们仍然重定向到/posts
而没有看到新创建的记录;我认为这是因为我们正在使用回调:: async
,所以搜索Kickick(和elasticsearch :: api :: Indices :: Indices :: Indicesclient
在幕后使用)无法了解排队搜索Kecrekick :: Reindexv2Job
。
如果是这样,那么如何解决此用例,即:#CREATE
或#destroy
操作已创建/销毁了搜索Kinkick-indexed记录,重定向在#index
操作中,请确保使用异步回调时的记录已经在索引上?
In a typical Rails controller, we create a Post
model and then redirect to posts_path
. The index
action uses Searchkick to list Posts.
# In the model
class Post < ApplicationRecord
searchkick callbacks: :async
end
# In the controller
def index
@posts = Post.search("*")
end
def create
Post.create!(post_params)
redirect_to posts_path
end
However, since Elasticsearch is eventually consistent, sometimes the redirect occur before Searchkick/Elasticsearch indexed that record.
Searchkick's docs state that one could use Post.search_index.refresh
to wait for the index to catch up with the new record. So one could write:
def create
Post.create!(post_params)
Post.search_index.refresh
redirect_to posts_path
end
However, sometimes we still redirect to /posts
without seeing the newly created record; I think that it's because we're using callbacks: :async
, so Searchkick (and Elasticsearch::API::Indices::IndicesClient
which is used behind the scenes) has no way to know about the queued Searchkick::ReindexV2Job
.
If that's the case, how does one solve this use-case, which is: after the #create
or #destroy
action have created/destroyed a Searchkick-indexed record, redirect to the #index
action making sure that the record is already on the index, when using async callbacks?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的猜测是正确的。您的背景作业可能尚未执行,因此刷新search_index无济于事。
为了解决问题,我们需要同步(在同一线程中)同步索引。幸运的是,您可以更改 Reindexing策略在运行时搜索Kackbacks。在您的情况下,我建议通过
搜索Kallbacks(:inline)
同步reindex :Your guess is correct. It's possible that your background job hasn't been executed yet, so refreshing the search_index won't help.
To fix the issue, we need to reindex synchronously (in the same thread). Luckily you can change the reindexing strategy of Searchkick callbacks in runtime. In your scenario, I recommend to reindex synchronously via
Searchkick.callbacks(:inline)
: