英文:
How to search multi-language items with elasticsearch
问题
Here's the translation of the provided text:
"我有一个使用Globalization Gem的Rails API应用程序。
我有一个Article
模型,其中包含id、created_at和updated_at
,这个模型有一个article_translations
表,其中包含title_en
和title_ar
,正文和摘要同样适用。
我设置了Elasticsearch,但只能使用一种语言。
这是我的关注文件:
# frozen_string_literal: true
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
mapping do
# 也尝试使用
# indexes :title, type: :text
indexes :title_en, type: :text
indexes :body_en, type: :text
indexes :excerpt_en, type: :text
indexes :title_ar, type: :text
indexes :body_ar, type: :text
indexes :excerpt_ar, type: :text
end
def self.search(query)
# 构建并运行搜索
params = {
query: {
bool: {
should: [
{ match: { title: { query: query, boost: 8, fuzziness: "AUTO" } }},
{ match: { body: { query: query, boost: 6, fuzziness: "AUTO" } }},
{ match: { excerpt: { query: query, boost: 4, fuzziness: "AUTO" } }},
]
}
},
}
self.__elasticsearch__.search(params)
end
end
end
现在当我使用Article.search('MyQuery')
时,它只搜索一种语言,这种语言是在运行Article.import(force: true)
时设置的。
所以,如果我运行上述命令,将I18n.locale = :en
,它将索引英文数据,对于阿拉伯文也是一样的。
由于在这里Globalization的工作方式如下:
Article.first.title
将返回带有英语区域设置的.title_en
和带有阿拉伯区域设置的.title_ar
,这是由用户设置的,当然,我们不添加_en
或_ar
,只是title
。
如果我想要索引两种语言以便在发送查询时能够同时搜索title_en
和title_ar
,该怎么办?
这是创建的索引:
在添加title_en
和title_ar
之后,如下图所示,但导入后被忽略:
提前致谢
英文:
So I have rails API app which uses Globalization Gem
I have and Article
model which has id, created_at and updated_at,
and this model has article_translations
table which contains title_en and title_ar
same applies for body and except
I set up Elasticsearch and it's working but with one language only
this is my concern file
# frozen_string_literal: true
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
mapping do
# Also tried using
# indexes :title, type: :text
indexes :title_en, type: :text
indexes :body_en, type: :text
indexes :excerpt_en, type: :text
indexes :title_ar, type: :text
indexes :body_ar, type: :text
indexes :excerpt_ar, type: :text
end
def self.search(query)
# build and run search
params = {
query: {
bool: {
should: [
{ match: { title: { query: query, boost: 8, fuzziness: "AUTO" } }},
{ match: { body: { query: query, boost: 6, fuzziness: "AUTO" } }},
{ match: { excerpt: { query: query, boost: 4, fuzziness: "AUTO" } }},
]
}
},
}
self.__elasticsearch__.search(params)
end
end
end
Now when i use Article.search('MyQuery')
it searches only on one language, the language which was set when Article.import(force: true)
ran
So if i ran the above command which I18n.locale = :en
it will index the english data, same for arabic
Since Globalization here works as following
Article.first.title
will return .title_en
with english locale and .title_ar
with arabic locale which is set by user, of course we don't add the _en
or the _ar
, just title
what if i want to index both languages to be able to search in both title_en
and title_ar
when i send a query ?
Here is the index created
and this is after adding title_en
& title_ar
but they are ignored after importing
Thanks in advance
答案1
得分: 0
Sure, here is the translated content:
"最终,我做到了!"
"我不确定这是否是最佳方式,但现在它正如预期般运作,支持两种语言 :)"
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
# 我不再需要这个了,因为
# 它在 as_indexed_json 方法上被覆盖了
#
# mapping do
# indexes :title, type: :text
# indexes :title_en, type: :text
# indexes :body_en, type: :text
# indexes :excerpt_en, type: :text
# indexes :title_ar, type: :text
# indexes :body_ar, type: :text
# indexes :excerpt_ar, type: :text
# end
def self.search(query)
# 构建并运行搜索
params = {
query: {
bool: {
should: [
{ match: { title_en: { query: query, boost: 8, fuzziness: "AUTO" } }},
{ match: { title_ar: { query: query, boost: 8, fuzziness: "AUTO" } }},
{ match: { body_en: { query: query, boost: 6, fuzziness: "AUTO" } }},
{ match: { body_ar: { query: query, boost: 6, fuzziness: "AUTO" } }},
{ match: { excerpt_en: { query: query, boost: 4, fuzziness: "AUTO" } }},
{ match: { excerpt_ar: { query: query, boost: 4, fuzziness: "AUTO" } }}
]
}
},
}
self.__elasticsearch__.search(params)
end
def as_indexed_json(options = nil)
self.as_json(
only: %i[title_en title_ar body_en body_ar excerpt_en excerpt_ar],
methods: %i[title_en title_ar body_en body_ar excerpt_en excerpt_ar]
)
end
end
end
英文:
Finally i did it!
I'm not sure if it's the best way to do it or not but now it's working as it should with both languages
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
# I Don't need this anymore because
# it's overridden on the as_indexed_json method
#
# mapping do
# indexes :title, type: :text
# indexes :title_en, type: :text
# indexes :body_en, type: :text
# indexes :excerpt_en, type: :text
# indexes :title_ar, type: :text
# indexes :body_ar, type: :text
# indexes :excerpt_ar, type: :text
# end
def self.search(query)
# build and run search
params = {
query: {
bool: {
should: [
{ match: { title_en: { query: query, boost: 8, fuzziness: "AUTO" } }},
{ match: { title_ar: { query: query, boost: 8, fuzziness: "AUTO" } }},
{ match: { body_en: { query: query, boost: 6, fuzziness: "AUTO" } }},
{ match: { body_ar: { query: query, boost: 6, fuzziness: "AUTO" } }},
{ match: { excerpt_en: { query: query, boost: 4, fuzziness: "AUTO" } }},
{ match: { excerpt_ar: { query: query, boost: 4, fuzziness: "AUTO" } }}
]
}
},
}
self.__elasticsearch__.search(params)
end
def as_indexed_json(options = nil)
self.as_json(
only: %i[title_en title_ar body_en body_ar excerpt_en excerpt_ar],
methods: %i[title_en title_ar body_en body_ar excerpt_en excerpt_ar]
)
end
end
end
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论