问题描述
说明
我正在尝试使用包括停用词在内的多词同义词进行查询。 先举个例子来解释一下。
我已将以下文档放入索引中。
- foo
- 栏
- foo 吧
- 酒吧的foo
- 脸书
查询 {"query":{"match":{"test":{"query":"foo of bar"}}}}
的预期结果是返回文档:
- foo 吧
- 酒吧的foo
- 脸书
配置
- stop:将移除的 标记
- synonym_graph:处理同义词fb,foo bar,foo of bar
映射
{
"properties": {
"test": {
"type": "text","analyzer": "test_index_analyzer","search_analyzer": "test_search_analyzer"
}
}
设置
{
"settings" : {
"index": {
"number_of_shards": 1,"number_of_replicas": 0,"analysis": {
"analyzer": {
"test_index_analyzer": {
"type": "custom","tokenizer": "whitespace","filter": [
"english_stop"
]
},"test_search_analyzer": {
"type": "custom","filter": [
"english_stop","english_syn"
]
}
},"filter": {
"english_stop": {
"type": "stop","stopwords": "_english_","ignore_case": true,"remove_trailing": false
},"english_syn": {
"type": "synonym_graph","synonyms": [
"fb,foo of bar","fb,foo bar"
]
}
}
}
}
}
}
结果
token 格式:"token,start_offset-end_offset,type/position/positionLength"
查询 | 搜索结果 | 索引分析 | 搜索分析 |
---|---|---|---|
fb | fb | fb,0-2,word,1 | foo,SYNONYM / 0 / 1 foo,SYNONYM / 0 / 3 fb,word / 0 / 4 bar,SYNONYM / 2 / 2 bar,SYNONYM / 3 / 1 |
栏的foo | fb | foo,0-3,1 bar,7-10,2,1 |
fb,0-10,SYNONYM / 0 / 3 foo,word / 0 / 1 bar,word / 2 / 1 |
foo bar | fb,foo bar | foo,4-7,1,0-7,SYNONYM / 0 / 2 foo,word / 1 / 1 |
所有搜索都希望返回 3 行:
- 脸书
- foo 吧
- 酒吧的foo
注意:bar 的 foo 永远不会返回
我的猜测是 foo of bar 被停止过滤器索引到位置 [foo,bar] 并且同义词正在寻找 [foo,bar]。
你对我的目标有什么建议吗?
解决方法
当您使用停用词过滤器时,单词的位置将被保留,因此如果您检查 bar of foo 的分析器结果,您将得到以下结果:
{
"tokens" : [
{
"token" : "foo","start_offset" : 0,"end_offset" : 3,"type" : "word","position" : 0
},{
"token" : "bar","start_offset" : 7,"end_offset" : 10,"position" : 2
}
]
}
如您所见,您在零位置获得了 'foo' 标记,在 2 位置获得了 'bar',因此同义词过滤器找不到此文档。
要解决您的问题,您应该先应用同义词过滤器,然后删除如下停用词。
"test_search_analyzer": {
"type": "custom","tokenizer": "whitespace","filter": [
"english_syn","english_stop"
]
}
并且您应该将“foo bar,foo of bar”添加到同义词列表中。
我认为保留停用词是必要的,因为它可以帮助获得更精确的搜索结果(尤其是 ES 使用的 BM25 相似度。),您可以查看有关它的弹性搜索官方文章here。