rails 上的 ruby 中未发现弹性搜索错误
elastic search not found error in ruby on rails
我将对 DoctorProfile 和 Subspeciality 进行弹性搜索 table。我正在处理的错误是它给出了未找到的结果。它从医生 table 那里获取了一个 id 列表,但它没有给出医生和副专业的期望结果。
这就是我所做的一切:
我使用了这些宝石:
gem 'elasticsearch-model', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-rails', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-extensions', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'
我的搜索方式:
def search
query = params[:query]
#query.encode("UTF-8")
if query.nil?
render json: { message: "no query is provided" }, status: :unprocessable_entity
return
end
profiles = DoctorProfile.search(query).results.map { |r| r._source.id }
subspecialties = Subspecialty.search(query).results.map { |r| r._source.title }
subspecialties.uniq!
profiles = profiles + DoctorProfile.where("subspeciality in (?)", subspecialties).ids
profiles.uniq!
logger.info "################ The profile is #{profiles} ########################"
@doctors = DoctorProfile.find(profiles)
@cleaned_doctors = @doctors.select { |u| !u.user.nil? }
render json: @cleaned_doctors
end
在医生模型中:
after_commit on: [:create] do
__elasticsearch__.index_document if self.enabled?
end
after_commit on: [:update] do
__elasticsearch__.update_document if self.enabled?
end
after_commit on: [:destroy] do
__elasticsearch__.delete_document
end
settings index: {
number_of_shards: 1,
number_of_replicas: 0,
analysis: {
filter: {
autocomplete_filter: {
type: "edge_ngram",
min_gram: 1,
max_gram: 20
}
},
analyzer: {
autocomplete: {
type: "custom",
tokenizer: "standard",
filter: [
"lowercase",
"autocomplete_filter"
]
}
}
}
}
mappings dynamic: 'false' do
indexes :first_name, type: "string"
indexes :last_name, type: "string"
indexes :medical_code, type: "string"
indexes :expertise, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
indexes :subspeciality, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
end
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
fields: ['medical_code^10', 'subspeciality^5', 'expertise^2', 'first_name', 'last_name']
}
}
}
)
在子专业模型中:
after_commit on: [:create] do
self.services = self.services.each {|str| str.force_encoding("UTF-8")}
__elasticsearch__.index_document if self.enabled?
end
after_commit on: [:update] do
self.services = self.services.each {|str| str.force_encoding("UTF-8")}
__elasticsearch__.update_document if self.enabled?
end
after_commit on: [:destroy] do
__elasticsearch__.delete_document
end
settings index: {
number_of_shards: 1,
number_of_replicas: 0,
analysis: {
filter: {
autocomplete_filter: {
type: "edge_ngram",
min_gram: 1,
max_gram: 20
}
},
analyzer: {
autocomplete: {
type: "custom",
tokenizer: "standard",
filter: [
"lowercase",
"autocomplete_filter"
]
}
}
}
}
mappings dynamic: 'false' do
indexes :description, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
indexes :services, type: "string"
end
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
fields: ['description', 'services']
}
}
}
)
end
这是我在日志中的错误:
Couldn't find all DoctorProfiles with 'id': (031addd8-9df8-4a53-974d-da0067302ad0, ff890720-4bfb-47d8-bdb8-3dc712b27f29, 869b28e1-cdd7-4bb6-b1d0-c7296e4b0637, 6dd6a784-c54b-4bb7-a0e1-337474ec4114, 234ccc87-f0c7-42f7-b96f-cf8d85487929, 543b621d-87aa-4a34-b6d6-62144c6a387e, 77e35144-9b93-48a0-a5bb-7b3addb99dff, d368f1df-3d1a-49ce-b6f5-f791df3294b1, d3dca8de-3143-4b03-90ec-e73a27c88960, 24abb0b3-2d11-457b-b95d-972462c4a37f) (found 2 results, but was looking for 10
我更改了这行代码
@doctors = DoctorProfile.find(profiles)
到
@doctors = DoctorProfile.where("id in (?)",profiles)
并删除这一行:
@cleaned_doctors = @doctors.select { |u| !u.user.nil? }
现在我想知道这个方法到底做了什么。
@cleaned_doctors = @doctors.select { |u| !u.user.nil? }
值得一提的是,我有一个 table 命名用户,doctorProfile 引用了它
你的代码没有说太多,但你的模型上似乎有一个布尔值enabled
,它告诉记录是否要被索引。
问题在于更新回调,因为如果您将模型从 enabled
更改为 not enabled
,而不是将其从索引中删除,它只是不会更新现有信息。
正确的回调是
after_commit on: [:update] do
if enabled?
if previous_changes['enabled'] &&
!previous_changes['enabled'].first
# previously not enabled, we need to index it
__elasticsearch__.index_document
else
# previously enabled, we need to update it
__elasticsearch__.update_document
end
else
# not enabled
if previous_changes['enabled'] &&
previous_changes['enabled'].first
# previously enabled, delete
__elasticsearch__.delete_document
end
# if it wasn't enabled before, it's not in the index anyway.
# do nothing
end
end
previous_changes
散列存储保存模型时确实更改的属性,因此您可以检查 enabled
属性的先前值。参见 http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-previous_changes
一旦你有了新的回调,重建索引以在需要时删除生产中的虚假数据:
DoctorProfile.where(enabled: true).find_each { |dp| dp.__elasticsearch__.index_document }
Subspecialty.where(enabled: true).find_each { |dp| dp.__elasticsearch__.index_document }
我将对 DoctorProfile 和 Subspeciality 进行弹性搜索 table。我正在处理的错误是它给出了未找到的结果。它从医生 table 那里获取了一个 id 列表,但它没有给出医生和副专业的期望结果。 这就是我所做的一切: 我使用了这些宝石:
gem 'elasticsearch-model', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-rails', git: 'git://github.com/elasticsearch/elasticsearch-rails.git'
gem 'elasticsearch-extensions', git: 'git://github.com/elasticsearch/elasticsearch-ruby.git'
我的搜索方式:
def search
query = params[:query]
#query.encode("UTF-8")
if query.nil?
render json: { message: "no query is provided" }, status: :unprocessable_entity
return
end
profiles = DoctorProfile.search(query).results.map { |r| r._source.id }
subspecialties = Subspecialty.search(query).results.map { |r| r._source.title }
subspecialties.uniq!
profiles = profiles + DoctorProfile.where("subspeciality in (?)", subspecialties).ids
profiles.uniq!
logger.info "################ The profile is #{profiles} ########################"
@doctors = DoctorProfile.find(profiles)
@cleaned_doctors = @doctors.select { |u| !u.user.nil? }
render json: @cleaned_doctors
end
在医生模型中:
after_commit on: [:create] do
__elasticsearch__.index_document if self.enabled?
end
after_commit on: [:update] do
__elasticsearch__.update_document if self.enabled?
end
after_commit on: [:destroy] do
__elasticsearch__.delete_document
end
settings index: {
number_of_shards: 1,
number_of_replicas: 0,
analysis: {
filter: {
autocomplete_filter: {
type: "edge_ngram",
min_gram: 1,
max_gram: 20
}
},
analyzer: {
autocomplete: {
type: "custom",
tokenizer: "standard",
filter: [
"lowercase",
"autocomplete_filter"
]
}
}
}
}
mappings dynamic: 'false' do
indexes :first_name, type: "string"
indexes :last_name, type: "string"
indexes :medical_code, type: "string"
indexes :expertise, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
indexes :subspeciality, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
end
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
fields: ['medical_code^10', 'subspeciality^5', 'expertise^2', 'first_name', 'last_name']
}
}
}
)
在子专业模型中:
after_commit on: [:create] do
self.services = self.services.each {|str| str.force_encoding("UTF-8")}
__elasticsearch__.index_document if self.enabled?
end
after_commit on: [:update] do
self.services = self.services.each {|str| str.force_encoding("UTF-8")}
__elasticsearch__.update_document if self.enabled?
end
after_commit on: [:destroy] do
__elasticsearch__.delete_document
end
settings index: {
number_of_shards: 1,
number_of_replicas: 0,
analysis: {
filter: {
autocomplete_filter: {
type: "edge_ngram",
min_gram: 1,
max_gram: 20
}
},
analyzer: {
autocomplete: {
type: "custom",
tokenizer: "standard",
filter: [
"lowercase",
"autocomplete_filter"
]
}
}
}
}
mappings dynamic: 'false' do
indexes :description, type: "string", analyzer: "autocomplete", search_analyzer: "standard"
indexes :services, type: "string"
end
def self.search(query)
__elasticsearch__.search(
{
query: {
multi_match: {
query: query,
fields: ['description', 'services']
}
}
}
)
end
这是我在日志中的错误:
Couldn't find all DoctorProfiles with 'id': (031addd8-9df8-4a53-974d-da0067302ad0, ff890720-4bfb-47d8-bdb8-3dc712b27f29, 869b28e1-cdd7-4bb6-b1d0-c7296e4b0637, 6dd6a784-c54b-4bb7-a0e1-337474ec4114, 234ccc87-f0c7-42f7-b96f-cf8d85487929, 543b621d-87aa-4a34-b6d6-62144c6a387e, 77e35144-9b93-48a0-a5bb-7b3addb99dff, d368f1df-3d1a-49ce-b6f5-f791df3294b1, d3dca8de-3143-4b03-90ec-e73a27c88960, 24abb0b3-2d11-457b-b95d-972462c4a37f) (found 2 results, but was looking for 10
我更改了这行代码
@doctors = DoctorProfile.find(profiles)
到
@doctors = DoctorProfile.where("id in (?)",profiles)
并删除这一行:
@cleaned_doctors = @doctors.select { |u| !u.user.nil? }
现在我想知道这个方法到底做了什么。
@cleaned_doctors = @doctors.select { |u| !u.user.nil? }
值得一提的是,我有一个 table 命名用户,doctorProfile 引用了它
你的代码没有说太多,但你的模型上似乎有一个布尔值enabled
,它告诉记录是否要被索引。
问题在于更新回调,因为如果您将模型从 enabled
更改为 not enabled
,而不是将其从索引中删除,它只是不会更新现有信息。
正确的回调是
after_commit on: [:update] do
if enabled?
if previous_changes['enabled'] &&
!previous_changes['enabled'].first
# previously not enabled, we need to index it
__elasticsearch__.index_document
else
# previously enabled, we need to update it
__elasticsearch__.update_document
end
else
# not enabled
if previous_changes['enabled'] &&
previous_changes['enabled'].first
# previously enabled, delete
__elasticsearch__.delete_document
end
# if it wasn't enabled before, it's not in the index anyway.
# do nothing
end
end
previous_changes
散列存储保存模型时确实更改的属性,因此您可以检查 enabled
属性的先前值。参见 http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-previous_changes
一旦你有了新的回调,重建索引以在需要时删除生产中的虚假数据:
DoctorProfile.where(enabled: true).find_each { |dp| dp.__elasticsearch__.index_document }
Subspecialty.where(enabled: true).find_each { |dp| dp.__elasticsearch__.index_document }