在弹性搜索中搜索子字符串 Java
Search for substring in Elastic Search Java
我正在使用弹性搜索并尝试在字段中查找子字符串。例如 - 在 stack overflow 中搜索字符串 tac 。我为此使用了 MultiMatchQuery,但它不起作用。这是我的代码片段(first_name 是字段名称)。
searchString = "*" + searchString.toLowerCase() + "*";
MultiMatchQueryBuilder mqb = new MultiMatchQueryBuilder("irs", first_name);
mqb.type(MultiMatchQueryBuilder.Type.PHRASE);
BoolQueryBuilder searchQuery = boolQuery();
searchQuery.should(mqb);
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withQuery(searchQuery);
NativeSearchQuery query = queryBuilder.build();
当我搜索 tac 时,return 没有任何结果。当我搜索 stack 或 overflow 时,它会 return stack overflow.
所以它会寻找准确的字符串。我尝试使用 MultiMatchQueryBuilder.Type.PHRASE_PREFIX
但它会查找以子字符串开头的短语。它适用于 stac 或 overf 但不适用于 tac 或 tack.
关于如何修复它有什么建议吗?
分析 Macth 查询并应用在索引期间应用的相同分析器,我相信您使用的是 standard
分析器,它生成了以下标记
POST http://localhost:9200/_analyze
{
"text": "stack overflow",
"analyzer" : "standard"
}
{
"tokens": [
{
"token": "stack",
"start_offset": 0,
"end_offset": 5,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "overflow",
"start_offset": 6,
"end_offset": 14,
"type": "<ALPHANUM>",
"position": 1
}
]
}
因此搜索 tac
与索引中的任何标记都不匹配,您需要更改分析器,使其将查询时间标记与索引时间标记相匹配。
n-gram tokenizer可以解决问题
示例
索引映射
{
"settings": {
"analysis": {
"filter": {
"autocomplete_filter": {
"type": "ngram",
"min_gram": 1,
"max_gram": 10
}
},
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
},
"index.max_ngram_diff" : 10
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "standard"
}
}
}
}
索引示例文档
{
"title" : "stack overflow"
}
和搜索查询
{
"query": {
"match": {
"title": "tac"
}
}
}
和搜索结果
"hits": [
{
"_index": "65241835",
"_type": "_doc",
"_id": "1",
"_score": 0.4739784,
"_source": {
"title": "stack overflow"
}
}
]
}
我正在使用弹性搜索并尝试在字段中查找子字符串。例如 - 在 stack overflow 中搜索字符串 tac 。我为此使用了 MultiMatchQuery,但它不起作用。这是我的代码片段(first_name 是字段名称)。
searchString = "*" + searchString.toLowerCase() + "*";
MultiMatchQueryBuilder mqb = new MultiMatchQueryBuilder("irs", first_name);
mqb.type(MultiMatchQueryBuilder.Type.PHRASE);
BoolQueryBuilder searchQuery = boolQuery();
searchQuery.should(mqb);
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withQuery(searchQuery);
NativeSearchQuery query = queryBuilder.build();
当我搜索 tac 时,return 没有任何结果。当我搜索 stack 或 overflow 时,它会 return stack overflow.
所以它会寻找准确的字符串。我尝试使用 MultiMatchQueryBuilder.Type.PHRASE_PREFIX
但它会查找以子字符串开头的短语。它适用于 stac 或 overf 但不适用于 tac 或 tack.
关于如何修复它有什么建议吗?
分析 Macth 查询并应用在索引期间应用的相同分析器,我相信您使用的是 standard
分析器,它生成了以下标记
POST http://localhost:9200/_analyze
{
"text": "stack overflow",
"analyzer" : "standard"
}
{
"tokens": [
{
"token": "stack",
"start_offset": 0,
"end_offset": 5,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "overflow",
"start_offset": 6,
"end_offset": 14,
"type": "<ALPHANUM>",
"position": 1
}
]
}
因此搜索 tac
与索引中的任何标记都不匹配,您需要更改分析器,使其将查询时间标记与索引时间标记相匹配。
n-gram tokenizer可以解决问题
示例
索引映射
{
"settings": {
"analysis": {
"filter": {
"autocomplete_filter": {
"type": "ngram",
"min_gram": 1,
"max_gram": 10
}
},
"analyzer": {
"autocomplete": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"autocomplete_filter"
]
}
}
},
"index.max_ngram_diff" : 10
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "autocomplete",
"search_analyzer": "standard"
}
}
}
}
索引示例文档
{
"title" : "stack overflow"
}
和搜索查询
{
"query": {
"match": {
"title": "tac"
}
}
}
和搜索结果
"hits": [
{
"_index": "65241835",
"_type": "_doc",
"_id": "1",
"_score": 0.4739784,
"_source": {
"title": "stack overflow"
}
}
]
}