我使用自定义分析器删除某组停用词。然后,我使用包含一些停用词的文本进行词组匹配查询。我希望停用词从查询中过滤掉,但它们不会(并且任何不包含停用词的文档都会被排除在结果之外)。
以下是我尝试做的简单示例:
#!/bin/bash
export ELASTICSEARCH_ENDPOINT="http://localhost:9200"
# Create index, with a custom analyzer to filter out the word 'foo'
curl -XPUT "$ELASTICSEARCH_ENDPOINT/play" -d '{
"settings": {
"analysis": {
"analyzer": {
"fooAnalyzer": {
"type": "custom",
"tokenizer": "letter",
"filter": [
"fooFilter"
]
}
},
"filter": {
"fooFilter": {
"type": "stop",
"stopwords": [
"foo"
]
}
}
}
},
"mappings": {
"myDocument": {
"properties": {
"myMessage": {
"analyzer": "fooAnalyzer",
"type": "string"
}
}
}
}
}'
# Add sample document
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d '
{"index":{"_index":"play","_type":"myDocument"}}
{"myMessage":"bar baz"}
'
如果我在查询中间使用过滤后的停用词对此索引执行phrase_match搜索,我希望它匹配(因为' foo'应该被我们的分析器过滤掉)。
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
"query": {
"match": {
"myMessage": {
"type": "phrase",
"query": "bar foo baz"
}
}
}
}
'
然而,我没有结果。
有没有办法指示Elasticsearch在执行搜索之前对查询字符串进行标记化和过滤?
编辑1:现在我更加困惑。我之前看到,如果我的查询在查询文本中间包含停用词,那么词组匹配就不起作用了。现在,此外,如果文档在查询文本的中间包含停用词,我发现短语查询不起作用。这是一个最小的例子,仍然使用上面的映射。
POST play/myDocument
{
"myMessage": "fib foo bar" <---- remember that 'foo' is a stopword and is filtered out of analysis
}
GET play/_search
{
"query": {
"match": {
"myMessage": {
"type": "phrase",
"query": "fib bar"
}
}
}
}
此查询不匹配。我对此感到非常惊讶!我希望foo stopword被过滤掉并被忽略。
有关我为什么会这样做的示例,请参阅此查询:
POST play/myDocument
{
"myMessage": "fib 123 bar"
}
GET play/_search
{
"query": {
"match": {
"myMessage": {
"type": "phrase",
"query": "fib bar"
}
}
}
}
这匹配,因为&#39; 123&#39;被我的字母&#39;过滤掉了标记生成器。似乎短语匹配完全忽略了禁用词过滤,并且好像这些标记一直在分析的字段中(即使它们不会出现在_analyze的标记列表中)。
我目前最好的解决方法:
稍后,在查询时:
答案 0 :(得分:0)
应该有效的解决方法:
_analyze
端点。这将从原始查询字符串返回标记,但为我删除讨厌的停用词但是,对于我的每个查询,这显然需要两次调用Elasticsearch。如果可能的话,我想找到更好的解决方案。
答案 1 :(得分:0)
事实证明,如果您想使用词组匹配,则令牌过滤器为时已晚,无法删除不需要的词。到那时,&#39;位置&#39;您的重要令牌字段因过滤令牌的存在而受到污染,并且短语匹配拒绝工作。
答案 - 在我们到达令牌过滤器级别之前进行过滤。我创建了一个char_filter来删除我们不需要的术语和短语匹配开始正常工作!
PUT play
{
"settings": {
"analysis": {
"analyzer": {
"fooAnalyzer": {
"type": "custom",
"tokenizer": "letter",
"char_filter": [
"fooFilter"
]
}
},
"char_filter": {
"fooFilter": {
"type": "pattern_replace",
"pattern": "(foo)",
"replacement": ""
}
}
}
},
"mappings": {
"myDocument": {
"properties": {
"myMessage": {
"analyzer": "fooAnalyzer",
"type": "string"
}
}
}
}
}
查询:
POST play/myDocument
{
"myMessage": "fib bar"
}
GET play/_search
{
"query": {
"match": {
"myMessage": {
"type": "phrase",
"query": "fib foo bar"
}
}
}
}
和
POST play/myDocument
{
"myMessage": "fib foo bar"
}
GET play/_search
{
"query": {
"match": {
"myMessage": {
"type": "phrase",
"query": "fib bar"
}
}
}
}
现在都有效!