我正在尝试为建议下拉菜单实现通配符。自从我试图弄清楚这一点以来,我已经有几天了。 :(
我有一份餐厅列表 (4000-7000)。我想在餐厅名称中使用通配符进行搜索,并首先显示搜索在文本前面的结果。
我尝试在没有分析器的情况下使用 ngram 分析器和我在网上找到的许多其他解决方案来索引名称字段,但没有成功。
目前我使用此设置获得的最佳结果:
settings:
analysis: {
analyzer: {
default: {
tokenizer: :keyword,
filter: [:lowercase]
}
}
}
索引名称字段是这样的:
indexes :name, type: :string, analyzer: :default
搜索:查询:{wildcard: {name: '*le*'}}
结果:Mr. Beef on Orleans、Miller's Pub、Merlo on Maple、Le Bouchon、Les Nomades、Leonardo's Ristorante、Lem's Bar-B-Q House、Le Petit Paris、Joy Yee's Noodles - Chinatown、J. Alexander's (林肯公园)、印度花园 - Streeterville、Goose Island Brewpub - Wrigleyville、Tweet ... Let's Eat!、Arco de Cuchilleros、Al 排名第一的意大利牛肉 - 小意大利
我希望以'le'开头的结果排在前面,有更高的分数。因为人们通常会搜索以 开头的餐厅。但是我不能在前面没有 * 的情况下进行搜索,因为我也想要包含它但结果得分较低的结果。例如上面的“Le Colonial”、“Le Petit Paris”、“Les Nomades”应该在前面。
我怎样才能做到这一点?
我担心的另一个问题是性能。我知道 booth 中的通配符结束了这是最坏的情况,但我找不到任何解决方案可以给我 ngram 或 shingle 的结果。
最佳答案
使用 boost 选择最上面的第一个匹配。
使用两个通配符查询
curl -XPOST "http://hostname:9200/index/type/_search" -d'
{
"size": 2000,
"query": {
"bool": {
"should": [
{
"wildcard": {
"name": {
"value": "*le*"
}
}
},
{
"wildcard": {
"name": {
"value": "le*",
"boost": 5
}
}
}
]
}
}
}'
使用一个通配符和一个前缀查询
curl -XPOST "http://hostname:9200/index/type/_search" -d'
{
"size": 2000,
"query": {
"bool": {
"should": [
{
"wildcard": {
"name": {
"value": "*le*"
}
}
},
{
"prefix": {
"name": {
"value": "le",
"boost": 2
}
}
}
]
}
}
}'
关于Elasticsearch 通配符搜索和相关性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23195991/