我正在尝试过滤掉所有删除的记录(使用偏执的gemhttps://github.com/goncalossilva/acts_as_paranoid)在Elasticsearch结果中。
acts_as_paranoid
是软删除,这个gem将覆盖我们模型的destroy
方法,它在我们的模型中添加了一个列名deleted_at (datetime)
,如果不删除这个记录,则设置为nil。在Elasticsearch中,我想过滤掉(所有删除的记录都不应该出现在搜索结果),但我仍然得到它们。
这是我在弹性搜索中的代码:
tire.search(load: true, page: params[:page], per_page: per_page) do
query do
boolean do
must { term: {"deleted_at": nil} }
end
filter :range, created_at: {gte: params[:created_after]} if params[:created_after]
filter :term, city: CITIES[params[:city]] unless CITIES[params[:city]].blank?
sort do
by :created_at, "desc"
end
end
end
我还试着把filter :missing, field: :deleted_at
但它没有正确工作。请告诉我我的错误是什么,我该如何改正?这让我疯了@@
首先要研究的是:
字段deleted_at是否编制了索引?
如果是,您的过滤器解决方案应该工作,否则
-
使用deleted_at清理所有文档,然后每当出现软删除时,您必须从弹性搜索中清理文档
-
您需要在索引中添加deleted_at,然后使用此筛选器。
如果你想进行第1步,你可以使用这段代码:
我看到您正在使用tire ruby客户端连接到elasticsearch:
获取deleted_at未设置为nil 的文档的ID
下面的代码应该可以
<Modelname>.all.map {|i| i.id if !usr.deleted_at.nil?}.compact #This is just an example no tests have been run to test the performance to fetch thousands of records.
你可以用别的东西。您只需要获取deleted_at未设置为nil的文档的ID
然后使用下面的代码从弹性搜索中删除这些文档。
id_array = [1,2,3]
query = Tire.search do |search|
search.query { |q| q.terms :_id, id_array }
end
index = Tire.index('<index_name>') # provide the index name as you have in your code
Tire::Configuration.client.delete "#{index.url}/_query?source=#{Tire::Utils.escape(query.to_hash[:query].to_json)}"
一旦完成这一操作,无论何时出现软删除,都必须使用相同的代码。你可以只发送数组中的单个id,而不是数字数组,或者你可以使用术语过滤器而不是术语来发送单个id
对于单个文档:
id_no = 1
query = Tire.search do |search|
search.query { |q| q.term :_id, id_no }
end
index = Tire.index('<index_name>') # provide the index name as you have in your code
Tire::Configuration.client.delete "#{index.url}/_query?source=#{Tire::Utils.escape(query.to_hash[:query].to_json)}"
如果要执行第2步,请在to_indexed.json中添加deleted_at,然后重新索引数据,然后使用过滤器。
您可以先删除索引,然后再创建它,在使用软删除之前,您的数据可能会受到索引的影响。
第1步:删除索引
bundle exec rake environment tire:index:drop force=true INDICES=<index_name>
第2步:再次创建索引
bundle exec rake environment tire:import:all force=true
使用http://localhost:9200/_aliases
检查<index_name>
(INDICES值)