gpt4 book ai didi

elasticsearch - 如何配置Elasticsearch在单词的开头或结尾找到子字符串(而不是在中间)?

转载 作者:行者123 更新时间:2023-12-03 01:03:48 28 4
gpt4 key购买 nike

我开始学习Elasticsearch,现在尝试编写我的第一个分析器配置。我想要实现的是,如果子字符串位于单词的开头或结尾,则可以找到它们。如果我有单词“stackoverflow”,并且搜索“stack”,我想找到它,当我搜索“flow”时,我想找到它,但是当我搜索“ackov”时,我不想找到它(在我的用例这是没有意义的)。

我知道有“Edge n gram标记器”,但是一个分析器只能有一个tokenizer,并且Edge n-gram可以在正面或背面(但不能同时在两者之间)。

而且,如果我正确理解了,将“Edge ngram filter”的两个版本(正反两个)应用于分析器,那么我将找不到任何一个,因为两个过滤器都需要返回true,不是吗?因为“stack”不会在单词的结尾,所以后沿n gram过滤器将返回false,并且不会找到单词“stackoverflow”。

因此,如何配置分析器以在单词的结尾或开头而不是在中间找到子字符串?

最佳答案

可以做的是定义两个分析器,一个用于在字符串的开头进行匹配,另一个用于在字符串的末尾进行匹配。在下面的索引设置中,我将前一个命名为prefix_edge_ngram_analyzer,将后一个命名为suffix_edge_ngram_analyzer。可以将这两个分析器分别应用于text.prefix子字段和text.suffix字符串字段的多字段字符串字段。

{
"settings": {
"analysis": {
"analyzer": {
"prefix_edge_ngram_analyzer": {
"tokenizer": "prefix_edge_ngram_tokenizer",
"filter": ["lowercase"]
},
"suffix_edge_ngram_analyzer": {
"tokenizer": "keyword",
"filter" : ["lowercase","reverse","suffix_edge_ngram_filter","reverse"]
}
},
"tokenizer": {
"prefix_edge_ngram_tokenizer": {
"type": "edgeNGram",
"min_gram": "2",
"max_gram": "25"
}
},
"filter": {
"suffix_edge_ngram_filter": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 25
}
}
}
},
"mappings": {
"test_type": {
"properties": {
"text": {
"type": "string",
"fields": {
"prefix": {
"type": "string",
"analyzer": "prefix_edge_ngram_analyzer"
},
"suffix": {
"type": "string",
"analyzer": "suffix_edge_ngram_analyzer"
}
}
}
}
}
}
}

然后,假设我们为以下测试文档建立索引:
PUT test_index/test_type/1
{ "text": "stackoverflow" }

然后,我们可以使用以下查询按前缀或后缀进行搜索:
# input is "stack" => 1 result
GET test_index/test_type/_search?q=text.prefix:stack OR text.suffix:stack

# input is "flow" => 1 result
GET test_index/test_type/_search?q=text.prefix:flow OR text.suffix:flow

# input is "ackov" => 0 result
GET test_index/test_type/_search?q=text.prefix:ackov OR text.suffix:ackov

使用查询DSL进行查询的另一种方法:
POST test_index/test_type/_search
{
"query": {
"multi_match": {
"query": "stack",
"fields": [ "text.*" ]
}
}
}

更新

如果您已经有一个字符串字段,则可以将其“升级”为多字段,并使用其分析器创建两个必需的子字段。这样做的方法是依次执行以下操作:
  • 关闭索引以创建分析器
    POST test_index/_close
  • 更新索引设置
    PUT test_index/_settings
    {
    "analysis": {
    "analyzer": {
    "prefix_edge_ngram_analyzer": {
    "tokenizer": "prefix_edge_ngram_tokenizer",
    "filter": ["lowercase"]
    },
    "suffix_edge_ngram_analyzer": {
    "tokenizer": "keyword",
    "filter" : ["lowercase","reverse","suffix_edge_ngram_filter","reverse"]
    }
    },
    "tokenizer": {
    "prefix_edge_ngram_tokenizer": {
    "type": "edgeNGram",
    "min_gram": "2",
    "max_gram": "25"
    }
    },
    "filter": {
    "suffix_edge_ngram_filter": {
    "type": "edgeNGram",
    "min_gram": 2,
    "max_gram": 25
    }
    }
    }
    }
  • 重新打开您的索引
    POST test_index/_open
  • 最后,更新您的文本字段的映射
    PUT test_index/_mapping/test_type
    {
    "properties": {
    "text": {
    "type": "string",
    "fields": {
    "prefix": {
    "type": "string",
    "analyzer": "prefix_edge_ngram_analyzer"
    },
    "suffix": {
    "type": "string",
    "analyzer": "suffix_edge_ngram_analyzer"
    }
    }
    }
    }
    }
  • 您仍然需要重新索引所有文档,以便填充和分析新的子字段text.prefixtext.suffix
  • 关于elasticsearch - 如何配置Elasticsearch在单词的开头或结尾找到子字符串(而不是在中间)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33595060/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com