我的用例:当用户可以键入他的查询时,我有一个搜索栏。除了常规查询建议之外,我还想向用户显示多种类型的搜索建议。例如,在下面的屏幕快照中,如您在此屏幕快照中所见,您可以看到有关公司部门,公司和学校的建议。
目前使用completion suggesters和以下映射实现(这是我们Ruby实现的代码,但我相信您应该能够轻松理解它)
{
_source: '',
suggest: {
text: query_from_the_user, # User query like "sec" to find "security" related matches
'school_names': {
completion: {
field: 'school_names_suggest',
},
},
'companies': {
completion: {
field: 'company_name.suggest',
},
},
'sectors': {
completion: {
field: sector_field_based_on_current_language(I18n.locale),
# uses 'company_sector.french.suggest' when the user browses in french
},
},
},
}
这是我的映射(这是用Ruby编写的,但我认为从心理上将其转换为Elasticsearch JSON配置应该不太难]
indexes :company_name, type: 'text' do
indexes :suggest, type: 'completion'
end
indexes :company_sector, type: 'object' do
indexes :french, type: 'text' do
indexes :suggest, type: 'completion'
end
indexes :english, type: 'text' do
indexes :suggest, type: 'completion'
end
end
indexes :school_names_suggest, type: 'completion'
# sample Indexed JSON
{
company_name: "Christian Dior Couture",
company_sector: {
english: 'Milk sector',
french: 'Secteur laitier'
},
school_names_suggest: ['Télécom ParisTech', 'Ecole Centrale Paris']
}
问题是建议的功能不够强大,无法根据句子的中间部分自动完成,即使完美匹配也无法提供其他结果。这是我需要通过ES实施捕获的一些方案
# documents
[{ company_name: "Christian Dior Couture" }]
# => A search term "Dior" should return this document because it matches by prefix on the second word
# documents
[
{ company_name: "Crédit Agricole" },
{ company_name: "Crédit Agricole Pyrénées Gascogne" },
]
# => A search term "Crédit Agricole" should return both documents (using the current implementation it only returns "Crédit Agricole"
我可以在Elasticsearch中使用建议者实现此功能吗?还是我需要回退到多个search
,它们将使用search-as-you-type
所提到的query
来利用新的in the doc数据类型?
我正在AWS和Ruby驱动程序(gem elasticsearch-7.3.0
)上使用elasticsearch 7.1
要回答您的问题,是的,使用Elasticsearch中的建议程序绝对可以实现。这仅取决于您如何实施它。
您有三个选择:
min_gram
,max_gram
等)query_string
我使用标准令牌生成器和nGram作为过滤器。这是我的设置:
{
"index": {
"index": "my_idx",
"type": "my_type",
"analysis": {
"index_analyzer": {
"my_index_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"mynGram"
]
}
},
"search_analyzer": {
"my_search_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"standard",
"lowercase",
"mynGram"
]
}
},
"filter": {
"mynGram": {
"type": "nGram",
"min_gram": 2,
"max_gram": 50
}
}
}
}
}
让您找到最多50个字母的单词部分。只需根据需要调整max_gram
。显然,该值越高,它将越慢。
使用query_string
,所有情况都将使用默认的标准分析仪:
我已将查询字符串添加到数据顶部,看起来像这样:
{
_source: '',
query : {
query_string: {
query: query_from_the_user
}
},
suggest: {
text: query_from_the_user, # User query like "sec" to find "security" related matches
'school_names': {
completion: {
field: 'school_names_suggest',
},
},
'companies': {
completion: {
field: 'company_name.suggest',
},
},
'sectors': {
completion: {
field: sector_field_based_on_current_language(I18n.locale),
# uses 'company_sector.french.suggest' when the user browses in french
},
},
},
}