一、效果图
1.1 拼音搜索
1.2 汉字搜索
现在需要实现输入拼音只匹配 第一个汉字,处于第二位和后面的不匹配,如果有大佬知道请赐教。
二、代码实现
2.1、相关环境搭建
1、安装ES(版本:5.0.0)
2、安装elasticsearch-analysis-ik(注意:版本和ES统一)
3、安装elasticsearch-analysis-pinyin(注意:版本和ES统一)
4、搭建springboot项目(springboot版本:2.0.4.RELEASE)
2.2、具体代码
1、springboot项目pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- elasticsearch启动器 (必须)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
<version>4.12</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.2.3</version>
<classifier>jdk15</classifier>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、 创建实体类Search
package com.example.entity;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.*;
@Mapping(mappingPath = "elasticsearch_mapping_search.json")//设置mapping
@Setting(settingPath = "elasticsearch_setting_search.json")//设置setting
@Document(indexName = "menusearch", type = "menu", shards = 1, replicas = 0)
public class Search {
@Id
private Long id;//id
@Field(type = FieldType.Text,analyzer = "pinyin_analyzer",searchAnalyzer = "pinyin_analyzer")
private String value;//菜单名称
@Field(type = FieldType.Keyword)
private String url;//菜单跳转地址
@Field(type = FieldType.Keyword)
private String type;//类型,是不是产品
@Field(type = FieldType.Keyword)
private String content;//
public Search() {
}
public Search(Long id, String value, String url, String type, String content) {
this.id = id;
this.value = value;
this.url = url;
this.type = type;
this.content = content;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "Search{" +
"id=" + id +
", value='" + value + '\'' +
", url='" + url + '\'' +
", type='" + type + '\'' +
", content='" + content + '\'' +
'}';
}
}
3、创建实体类对应的配置文件elasticsearch_mapping_search.json(放在项目resources目录下)
{
"menu": {
"properties": {
"content": {
"type": "keyword",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"type": {
"type": "keyword",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
} ,
"url": {
"type": "keyword",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "text",
"analyzer": "pinyin_analyzer",
"search_analyzer": "pinyin_analyzer",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
}
4、创建实体类对应的配置文件elasticsearch_setting_search.json(放在项目resources目录下)
{
"index": {
"analysis": {
"analyzer": {
"pinyin_analyzer": {
"tokenizer": "my_pinyin"
}
},
"tokenizer": {
"my_pinyin": {
"type": "pinyin",
//true:支持首字母
"keep_first_letter": true,
"first_letter" : "prefix",
//false:首字母搜索只有两个首字母相同才能命中,全拼能命中
//true:任何情况全拼,首字母都能命中
"keep_separate_first_letter": true,
//true:支持全拼 eg: 刘德华 -> [liu,de,hua]
"keep_full_pinyin": true,
"keep_original": true,
"keep_none_chinese": true,
"keep_none_chinese_in_first_letter": true,
//设置最大长度
"limit_first_letter_length": 16,
"lowercase": true,
"trim_whitespace": true,
//重复的项将被删除,eg: 德的 -> de
"remove_duplicated_term": true
}
}
}
}
}
5、创建接口
package com.example.demo;
import com.example.entity.Search;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface SearchReposity extends ElasticsearchRepository<Search,Long> {
}
6、业务代码实现
package com.example.demo;
import com.example.entity.Search;
import net.sf.json.JSONObject;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class HelloController {
@Autowired
private SearchReposity searchReposity;
@RequestMapping("/search")
@ResponseBody
public String searchByPinYin(HttpServletRequest request, HttpServletResponse response){
String content = request.getParameter("keywords");
WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("value", content+"*");
Iterable<Search> iterable = searchReposity.search(wildcardQueryBuilder);
JSONObject jsonObject = JSONObject.fromObject(iterable);
return jsonObject.toString();
}
}