es搜索实现既能模糊查询又能分词查询

现在有一个es的字段,希望它既能分词查询,又能有模糊查询怎么办?
只有分词查询的坏处:
可能单个字反而搜不出来,比如一个“南京”,搜“南”字就搜不出来,反而降低体验。
想让es既能分词又能模糊查询有几种办法:

方案一:利用 keyword 子字段实现精确与模糊搜索并存

实现原理

通过为 name 字段添加 keyword 子字段,使其既能进行分词搜索(利用 name 字段自身),又能实现精确或模糊搜索(借助 name.keyword 子字段)。
具体操作步骤

重新定义索引映射

PUT /ebox_material_bizitem/_mapping
{
  "properties": {
    "name": {
      "type": "text",
      "fields": {
        "keyword": {
          "type": "keyword",
          "ignore_above": 256
        }
      }
    }
  }
}

搜索:

GET /ebox_material_bizitem/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "name": "四" } },          // 分词搜索(如:匹配"四川"、"四季")
        { "wildcard": { "name.keyword": "*四*" } }  // 模糊搜索(需完整包含"四")
      ],
      "minimum_should_match": 1
    }
  }
}

代码:

nameQuery := elastic.NewBoolQuery().
        Should(
            elastic.NewMatchQuery("name", req.GetName()),          // 分词搜索
            elastic.NewWildcardQuery("name.keyword", "*"+req.GetName()+"*"),  // 模糊搜索
        ).
        MinimumNumberShouldMatch(1)
    queryArgs = append(queryArgs, es.WithMust(nameQuery))

方案二:运用自定义分词器实现多粒度分词

实现原理

创建一个自定义分词器,将文本同时分词为单字和词语,从而兼顾模糊搜索和分词搜索的需求。

方案三:结合 match 和 wildcard 查询

实现原理

在同一个查询中同时使用 match 查询(用于分词搜索)和 wildcard 查询(用于模糊搜索),然后通过 bool.should 将它们组合起来。

GET /ebox_material_bizitem/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": {
              "query": "四",
              "boost": 2  // 提高分词搜索的权重
            }
          }
        },
        {
          "wildcard": {
            "name": {
              "value": "*四*",
              "boost": 1  // 降低模糊搜索的权重
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

用代码实现:

if req.GetName() != "" {
		nameQuery := elastic.NewBoolQuery().
			Should(
				elastic.NewMatchQuery("name", req.GetName()).Boost(2),            // 提高分词搜索权重
				elastic.NewWildcardQuery("name", "*"+req.GetName()+"*").Boost(1), // 降低模糊搜索权重
			).
			MinimumNumberShouldMatch(1)
		queryArgs = append(queryArgs, es.WithMust(nameQuery))
	}
RestHighLevelClient 是 Elasticsearch 官方提供的 Java 客户端,可以通过它来实现分词、模糊、相似度查询。其中,分词查询可以使用 match 查询,模糊查询可以使用 fuzzy 查询,相似度查询可以使用 more_like_this 查询。 例如,使用 match 查询实现分词查询: ```java SearchRequest searchRequest = new SearchRequest("index"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("field", "query"); searchSourceBuilder.query(matchQueryBuilder); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); ``` 使用 fuzzy 查询实现模糊查询: ```java SearchRequest searchRequest = new SearchRequest("index"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("field", "query"); searchSourceBuilder.query(fuzzyQueryBuilder); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); ``` 使用 more_like_this 查询实现相似度查询: ```java SearchRequest searchRequest = new SearchRequest("index"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders.moreLikeThisQuery(new String[]{"field1", "field2"}, new String[]{"like_text1", "like_text2"}, null); searchSourceBuilder.query(moreLikeThisQueryBuilder); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值