首先说一下,es的版本号很重要,版本号不对,各种失败。我是先装的es,kibana,后新建的项目,结果启动报错,日志写着用高版本es,直接重装了又。
我的spring-boot-starter-parent是2.4.5版本,对应的es是7.9.3,启动的时候会有日志显示。
pom中添加es依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
application.yml
spring:
elasticsearch:
rest:
uris: 192.168.2.232:9200
地址默认的是localhost:9200,spring.data.elasticsearch.cluster-name这个已经过时
会发现很多方法和配置,都是过时了
- entity
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.*;
@Data
@Document(indexName = "news")
@AllArgsConstructor
public class News {
@Id
private Integer id;
// @Field(type = FieldType.Text,analyzer = "ik_max_word")
@MultiField(mainField = @Field(type = FieldType.Text, analyzer = "ik_max_word")
, otherFields = @InnerField(suffix = "inner", type = FieldType.Text, analyzer = "pinyin"))
private String content;
}
Document这个是属于es包下面的注解,indexName就是索引名称,默认createIndex=true,即没有该索引,会创建。
@Id,索引的id
之前我用的@Field注解,就标明映射类型,@MultiField是多个映射类型,这里我用的是拼音和分词,要提前下载对应es版本的插件包,放到plugins文件夹下面
https://github.com/medcl/
就这两个,有些插件官网下载也是可以的,点进去会找到下载zip的地址,一定要版本对应
记着重启es,启动日志上会写上加载了plugins下面的具体插件文件夹
- repository,这个就有点类似mybatis-plus了
public interface NewsRepository extends ElasticsearchRepository<News,Integer> {
}
- controller
@RestController
@AllArgsConstructor
@RequestMapping("/es")
public class EsController {
private final NewsRepository newsRepository;
private final ElasticsearchRestTemplate elasticsearchRestTemplate;
// @PostConstruct
// public void init(){
// 这个方法也过时了
// elasticsearchRestTemplate.putMapping(News.class);
// }
@GetMapping("/new/list")
public Object list(){
return newsRepository.findAll();
}
@GetMapping("/news/save")
public Object save(){
List<News> list = new ArrayList<>();
list.add(new News(1, "张三带球"));
list.add(new News(2, "李四上网"));
list.add(new News(3, "王五抽烟"));
list.add(new News(4, "赵六喝酒"));
list.add(new News(5, "张七带饭"));
Iterable<News> news = newsRepository.saveAll(list);
return news;
}
@GetMapping("/news/getByContent")
public Object getByContent(@RequestParam("content")String content) {
//高亮
String preTag = "<font color='red'>";
String postTag = "</font>";
// BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder().should(new MatchQueryBuilder("content", content));
// Query query = new NativeSearchQueryBuilder()
// .withQuery(boolQueryBuilder)
// .withHighlightFields(new HighlightBuilder.Field("content").preTags(preTag).postTags(postTag)).build();
Query query1 = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(content,"content","content.inner")).build();
// .withQuery(QueryBuilders.queryStringQuery(content)).build();
SearchHits<News> search = elasticsearchRestTemplate.search(query1, News.class);
return search;
}
}
启动项目,这时候查看es就会创建这个索引
我这遇到一个问题,拼音一直不起作用,后来发现是mapping的问题
如果用kibana这种可视化工具,可以查看索引,看索引对应的mapping
或者 GET es的ip:端口/索引名/_mapping
我是在 kibana上 GET /news/_mapping
得到的结果
{
"news" : {
"mappings" : {
"properties" : {
"content" : {
"type" : "text",
"fields" : {
"inner" : {
"type" : "text",
"analyzer" : "pinyin"
}
},
"analyzer" : "ik_max_word"
}
}
}
}
}
只有mapping是这样,才确定了实体类上的@MultiField是没有问题的,如果不行,删除索引,重新启动项目,或者执行
elasticsearchRestTemplate.putMapping(News.class); 这个就行了,在controller中,我注释掉了,我就是删除也不行,执行了这个就好了。
也可以在kibana或者postman上(ip:端口)执行,kibana上不用加ip
GET /_analyze
{
"analyzer": "pinyin",
"text": "张三带球"
}
返回信息
{
"tokens" : [
{
"token" : "zhang",
"start_offset" : 0,
"end_offset" : 0,
"type" : "word",
"position" : 0
},
{
"token" : "zsdq",
"start_offset" : 0,
"end_offset" : 0,
"type" : "word",
"position" : 0
},
{
"token" : "san",
"start_offset" : 0,
"end_offset" : 0,
"type" : "word",
"position" : 1
},
{
"token" : "dai",
"start_offset" : 0,
"end_offset" : 0,
"type" : "word",
"position" : 2
},
{
"token" : "qiu",
"start_offset" : 0,
"end_offset" : 0,
"type" : "word",
"position" : 3
}
]
}
这样,就标识拼音插件安装是没问题的
GET /_analyze
{
"text": "中华人民共和国人民大会堂",
"analyzer": "ik_max_word"
}
这个分词插件,返回的太多了,我就不上代码了,会返回各种词组
controller中 getByContent,前面注释的是高亮显示的方法,没注释的,就是拼音,分词都行,再自行摸索吧,我也是看的别的,很懵逼
Query的实现类AbstractQuery,还有一个CriteriaQuery也继承了它,但是没找到具体咋用,所以就用NativeSearchQuery 这个了。