在Elastic Search Java中搜索子字符串



我正在使用弹性搜索,并试图在字段中查找子字符串。例如,在堆栈溢出中搜索字符串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时,它不会返回任何结果。当我搜索堆栈溢出时,它确实返回

栈溢出所以它会寻找确切的字符串。我尝试使用MultiMatchQueryBuilder.Type.PHRASE_PREFIX,但它会查找以子字符串开头的短语。它适用于stackoverf之类的字符串,但不适用于tactack

关于如何修复它,有什么建议吗?

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标记器可以解决这个问题。

示例

索引映射

{
"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"
}
}
]
}

最新更新