ElasticSearch+SpringBoot实现汉语、拼音模糊搜索简单demo

一、效果图

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();
    }
}




 

 

 

 

猜你喜欢

转载自blog.csdn.net/Micheal_yang0319/article/details/105454924