在弹性搜索中搜索子字符串 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 没有任何结果。当我搜索 stackoverflow 时,它会 return stack overflow.

所以它会寻找准确的字符串。我尝试使用 MultiMatchQueryBuilder.Type.PHRASE_PREFIX 但它会查找以子字符串开头的短语。它适用于 stacoverf 但不适用于 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 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"
                }
            }
        ]
    }