Elasticsearch的安装和使用
下载Elasticsearch6.2.2的zip包,并解压到指定目录,下载地址:
https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-2-2
安装中文分词插件,在elasticsearch-6.2.2\bin目录下执行以下命令:
elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.2.2/elasticsearch-analysis-ik-6.2.2.zip
运行bin目录下的elasticsearch.bat启动Elasticsearch
下载Kibana,作为访问Elasticsearch的客户端,请下载6.2.2版本的zip包,并解压到指定目录,下载地址:https://artifacts.elastic.co/downloads/kibana/kibana-6.2.2-windows-x86_64.zip
运行bin目录下的kibana.bat,启动Kibana的用户界面
访问http://localhost:5601 即可打开Kibana的用户界面
Get Put命令学习参考
https://www.xugj520.cn/archives/exploring_cluster.html
Springboot 整合Elasticsearch
版本参考
版本对应很重要 我的是
springboot 2.1.3.RELEASE
es 6.2.2
spring data es 3.1.16.RELEASE
在pom.xml中添加相关依赖
org.springframework.data
spring-data-elasticsearch
3.1.16.RELEASE
修改SpringBoot配置文件
修改application.yml文件,在spring节点下添加Elasticsearch相关配置。
# elasticsearch相关配置 .yml全局只能有一个spring注意
spring:
data:
elasticsearch:
cluster-name: elasticsearch # es集群的名称
cluster-nodes: 127.0.0.1:9300 # 程序连接es的端口号是9300
Model
先写一个的商品实体类,借助这个实体类来完成基础的CRUD功能
package com.wg.biye.wgcore.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
//@Accessors @Data 是lombok的注解
//6.0版本以后,一个index下,只允许创建一个type,不允许存在多个type 并且在官网提供信息,7.0以后不再使用type。
@Data
@Accessors(chain = true)
@Document(indexName = "wgaituwang", type = "product",shards = 1,replicas = 0)//必须小写
public class WgProduct implements Serializable {
/*
不需要中文分词的字段设置成@Field(type = FieldType.Keyword)类型,需要中文分词的设置成@Field(analyzer = "ik_max_word",type = FieldType.Text)类型。
* */
private static final long serialVersionUID = -1L;
@Id
private String id;//必须添加@Id注解,最好为String类型
@Field(analyzer = "ik_max_word",type = FieldType.Text)//IK分词器
private String name;//商品名称
private String productAddress;//商品出产地
private String keywords;//商品关键字
@Field(analyzer = "ik_max_word",type = FieldType.Text)
private String title;//商品标题
private Double price;//价格
// private String time;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date time;
/*
{
"id" : "1",
"name" : "火龙果",
"productAddress" : "北京天安门",
"keywords" : "水果",
"title" : "香甜可口的火龙果",
"price" : "100",
"time" : "2020-03-27"
}
*/
}
常用注解学习
@Document
属性名 | 类型 | 含义 |
---|---|---|
indexName | String | 索引库名字,相当于mysql中数据库的概念 |
type | String | 文档类型,mysql中表的概念 |
shards | short | 默认分片数 默认值5 |
replicas | short | 默认副本数量 默认值1 |
@Id
可以认为是mysql中表一行的Id概念
@Field
public @interface Field {
//文档中字段的类型
FieldType type() default FieldType.Auto;
//是否建立倒排索引
boolean index() default true;
//是否进行存储
boolean store() default false;
//分词器名次
String analyzer() default "";
}
其中字段类型的选项有
//为文档自动指定元数据类型
public enum FieldType {
Text,//会进行分词并建了索引的字符类型
Integer,
Long,
Date,
Float,
Double,
Boolean,
Object,
Auto,//自动判断字段类型
Nested,//嵌套对象类型
Ip,
Attachment,
Keyword//不会进行分词建立索引的类型
}
创建repository包
创建实体类的接口继承ElasticsearchRepository这样就有基本的CRUD(用过Jpa的就很清楚)
package com.wg.biye.wgcore.repository;
import com.wg.biye.wgcore.entity.WgProduct;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface WgProductRepository extends ElasticsearchRepository {
}
我们就直接实现控制类吧
package com.wg.biye.wgcore.controller;
import com.wg.biye.common.util.ResultUtil;
import com.wg.biye.wgcore.entity.WgProduct;
import com.wg.biye.wgcore.repository.WgProductRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
//需要一个工具将MySQL的数据导入Elasticsearch
//@RestController = @Controller + @ResponseBody组成
@RestController
@RequestMapping("/wgproduct")
public class WgProductController {
@Autowired
private WgProductRepository wgProductRepository;
//@RequestBody学习 : https://blog.csdn.net/justry_deng/article/details/80972817
@PostMapping("/add")
public Map add(@RequestBody WgProduct wgProduct) {
System.out.println(wgProduct.toString());
System.out.println(wgProduct instanceof WgProduct);//true
wgProductRepository.save(wgProduct);
return ResultUtil.resultCode(200,"添加商品成功"); ResultUtil工具换成自己的就行
}
//根据Id查询
@GetMapping("/get/{id}")
public Map getById(@PathVariable String id) {
Map result = new HashMap<>();
if (StringUtils.isEmpty(id))
return ResultUtil.resultCode(500,"Id为空");
//【java8新特性】Optional详解 https://www.jianshu.com/p/d81a5f7c9c4e
Optional wgProductOptional = wgProductRepository.findById(id);
if (wgProductOptional.isPresent()) {//isPresent()方法用于判断包装对象的值是否非空
WgProduct wgProduct = wgProductOptional.get();
result.put("商品信息",wgProduct);
return ResultUtil.resultSuccess(result);
}
return ResultUtil.resultError(result);
}
//查询所有
@GetMapping("/getall")
public Map getAll() {
Map result = new HashMap<>();
Iterable iterable = wgProductRepository.findAll();
List list = new ArrayList<>();
iterable.forEach(list::add);
result.put("所有商品",list);
return ResultUtil.resultSuccess(result);
}
// 根据ID修改
@PostMapping("/update")
public Map updateById(@RequestBody WgProduct wgProduct) {
String id = wgProduct.getId();
if (StringUtils.isEmpty(id))
return ResultUtil.resultCode(500,"Id为空");
wgProductRepository.save(wgProduct);
return ResultUtil.resultCode(200,"修改商品成功");
}
// 根据ID删除
@DeleteMapping("/delete/{id}")
public Map deleteById(@PathVariable String id) {
if (StringUtils.isEmpty(id))
return ResultUtil.resultCode(500,"Id为空");
wgProductRepository.deleteById(id);
return ResultUtil.resultCode(200,"删除商品成功");
}
}
POSTMAN测试
增加
查看
删除
搜索
构造数据 在测试类胡乱写
package com.wg.biye;
import com.wg.biye.wgcore.entity.*;
import com.wg.biye.wgcore.repository.WgProductRepository;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Date;
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class BiyeApplicationTests {
@Autowired
private WgProductRepository wgProductRepository;
@Test
public void contextLoads() {
WgProduct wgProduct = new WgProduct();
wgProduct.setId("100");
wgProduct.setTitle("好吃的");
wgProduct.setProductAddress("北京");
wgProduct.setPrice(20.0);
wgProduct.setTime(new Date());
wgProduct.setKeywords("水果");
wgProduct.setName("梨");
wgProductRepository.save(wgProduct);
wgProduct.setId("101");
wgProduct.setTitle("好玩的");
wgProduct.setProductAddress("成都");
wgProduct.setPrice(20.0);
wgProduct.setTime(new Date());
wgProduct.setKeywords("水果");
wgProduct.setName("梨");
wgProductRepository.save(wgProduct);
wgProduct.setId("102");
wgProduct.setTitle("好喝的");
wgProduct.setProductAddress("成都");
wgProduct.setPrice(20.0);
wgProduct.setTime(new Date());
wgProduct.setKeywords("饮料");
wgProduct.setName("梨");
wgProductRepository.save(wgProduct);
wgProduct.setId("103");
wgProduct.setTitle("好玩的");
wgProduct.setProductAddress("北京");
wgProduct.setPrice(20.0);
wgProduct.setTime(new Date());
wgProduct.setKeywords("玩具");
wgProduct.setName("梨");
wgProductRepository.save(wgProduct);
wgProduct.setId("104");
wgProduct.setTitle("好吃的");
wgProduct.setProductAddress("北京");
wgProduct.setPrice(20.0);
wgProduct.setTime(new Date());
wgProduct.setKeywords("水果");
wgProduct.setName("梨");
wgProductRepository.save(wgProduct);
wgProduct.setId("105");
wgProduct.setTitle("好吃的");
wgProduct.setProductAddress("成都");
wgProduct.setPrice(20.0);
wgProduct.setTime(new Date());
wgProduct.setKeywords("水果");
wgProduct.setName("梨");
wgProductRepository.save(wgProduct);
wgProduct.setId("106");
wgProduct.setTitle("好吃的");
wgProduct.setProductAddress("北京");
wgProduct.setPrice(20.0);
wgProduct.setTime(new Date());
wgProduct.setKeywords("水果");
wgProduct.setName("梨");
wgProductRepository.save(wgProduct);
}
}
查询所有数据
搜索标题中以关键字开头的方法
WgProductRepository.class添加方法
List findAllByTitleLike(String s);
控制器添加
@GetMapping("/search/title")
public Map repSearchTitle(String keyword) {
if (StringUtils.isEmpty(keyword))
return ResultUtil.resultCode(500,"条件为空");
Map result = new HashMap<>();
List list = new ArrayList<>();
list = wgProductRepository.findAByTitleLike(keyword);
result.put("搜索结果",list);
return ResultUtil.resultSuccess(result);
}
搜索结果
{
"code": 200,
"搜索结果": [
{
"id": "100",
"name": "梨",
"productAddress": "北京",
"keywords": "水果",
"title": "好吃的",
"price": 20.0,
"time": "2020-03-27"
},
{
"id": "104",
"name": "梨",
"productAddress": "北京",
"keywords": "水果",
"title": "好吃的",
"price": 20.0,
"time": "2020-03-27"
},
{
"id": "105",
"name": "梨",
"productAddress": "成都",
"keywords": "水果",
"title": "好吃的",
"price": 20.0,
"time": "2020-03-27"
},
{
"id": "106",
"name": "梨",
"productAddress": "北京",
"keywords": "水果",
"title": "好吃的",
"price": 20.0,
"time": "2020-03-27"
}
],
"message": "操作成功"
}
更多API请参考
https://docs.spring.io/spring-data/elasticsearch/docs/3.1.16.RELEASE/reference/html/#populator.namespace-dao-config