1. 今日内容
1.java-client操作ES
2.sde操作ES
一、Java Rest Client
https://www.elastic.co/guide/en/elasticsearch/client/index.html
1.创建项目
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<!--es 高级版本操作坐标-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.8.3</version>
</dependency>
<!--es依赖-->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.8.3</version>
</dependency>
2. 文档代码操作
#语句
PUT /heima
{
"mappings": {
"product": {
"properties": {
"id": {
"type": "keyword"
},
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"category": {
"type": "keyword"
},
"brand": {
"type": "keyword"
},
"images": {
"type": "keyword",
"index": false
},
"price": {
"type": "double"
}
}
}
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Product {
private Long id;
/**
* 标题
*/
private String title;
/**
* 分类
*/
private String category;
/**
* 品牌
*/
private String brand;
/**
* 价格
*/
private Double price;
/**
* 图片地址
*/
private String images;
}
Test01
import com.alibaba.fastjson.JSON;
import com.itheima.pojo.Product;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
/**
* <dl>
* <dd>描述: ~ Test01</dd>
* <dd>创建时间: 10:06 2020/9/25</dd>
* <dd>创建人: guodong</dd>
* <dt>版本历史: </dt>
* <pre>
* Date Author Version Description
* ------------------------------------------------------------------
* 2020/9/25 guodong 1.0 1.0 Version
* </pre>
* </dl>
*/
public class Test01 {
RestHighLevelClient client;
//1.创建连接
@Before
public void initClient(){
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")/*,
new HttpHost("localhost", 9201, "http")*/));
}
/**
* @Author: guodong
* @Date: 10:13 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 新增数据
*/
@Test
public void createDoc(){
//1.创建发送数据---》json(产品json字符串)
Product product = new Product(1l,"小米手机","手机","小米",2699.00,"http://www.baidu.com");
String jsonString = JSON.toJSONString(product);
//2.创建请求对象---》indexRequest指定索引库名称、类型名称、_id(可选)
IndexRequest indexRequest = new IndexRequest("heima","product","1");
//3.将数据封装到请求对象中
indexRequest.source(jsonString, XContentType.JSON);
//4.发送请求---》client
try {
IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
//5.打印响应结果
System.out.println("响应结果: " + indexResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Author: guodong
* @Date: 10:25 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 根据id查询文档
*/
@Test
public void getDocById(){
//1.创建请求对象---》GetRequest 指定索引库名称、类型名称、_id
GetRequest getRequest = new GetRequest("heima","product","1");
//2.发送请求
try {
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
//3.打印结果
System.out.println("响应结果: " + getResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Author: guodong
* @Date: 10:30 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 根据id修改文档
*/
@Test
public void updateDocById(){
//1.创建请求对象--》updateRequest 指定索引库名称、类型名称、_id
UpdateRequest updateRequest = new UpdateRequest("heima","product","1");
//2.创建发送数据---》json(产品json字符串)
Product product = new Product(1l,"大米手机","手机","大米",19999.00,"http://www.baidu.com");
String jsonString = JSON.toJSONString(product);
//3.将修改数据添加至请求对象
updateRequest.doc(jsonString, XContentType.JSON);
//4.发送请求
try {
UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
//5.打印结果
System.out.println("响应结果: " + updateResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @Author: guodong
* @Date: 10:35 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 根据id删除---》作业
*/
@Test
public void deleteById(){
}
/**
* @Author: guodong
* @Date: 10:36 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 批量添加数据
*/
@Test
public void batchAddDoc(){
//1.创建BulkRequest 批处理对象
BulkRequest bulkRequest = new BulkRequest();
for (long i = 2; i < 10; i++) {
//2.创建发送数据---》json(产品json字符串)
Product product = new Product(i,"小米手机" + i,"手机","小米",2699.00+i,"http://www.baidu.com");
String jsonString = JSON.toJSONString(product);
//3.创建请求对象---》indexRequest指定索引库名称、类型名称、_id(可选)
IndexRequest indexRequest = new IndexRequest("heima","product",i+"");
//4.将数据封装到请求对象中
indexRequest.source(jsonString, XContentType.JSON);
//5.将indexRequest对象封装到BulkRequest
bulkRequest.add(indexRequest);
}
//6.发送请求
try {
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
} catch (IOException e) {
e.printStackTrace();
}
}
//2.释放资源
@After
public void closeClient(){
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Test02
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.Map;
/**
* <dl>
* <dd>描述: ~ Test01</dd>
* <dd>创建时间: 10:06 2020/9/25</dd>
* <dd>创建人: guodong</dd>
* <dt>版本历史: </dt>
* <pre>
* Date Author Version Description
* ------------------------------------------------------------------
* 2020/9/25 guodong 1.0 1.0 Version
* </pre>
* </dl>
*/
public class Test02 {
RestHighLevelClient client;
//1.创建连接
@Before
public void initClient(){
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")/*,
new HttpHost("localhost", 9201, "http")*/));
}
/**
* @Author: guodong
* @Date: 11:08 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 根据条件查询
*/
@Test
public void matchDoc(){
//3.创建QueryBuilder,需要使用工厂方法,并且需指定查询的字段和条件
QueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "小米");
commonQuery(queryBuilder);
}
/**
* @Author: guodong
* @Date: 11:19 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 查询所有
*/
@Test
public void matchAll(){
QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
commonQuery(queryBuilder);
}
/**
* @Author: guodong
* @Date: 11:26 2020/9/25
* @Parms [queryBuilder]
* @ReturnType: void
* @Description: 公共查询方法
*/
private void commonQuery(QueryBuilder queryBuilder) {
//1. 创建SearchRequest对象指定索引库名称
SearchRequest searchRequest = new SearchRequest("heima");
//2.创建SearchSourceBuilder
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//4.将QueryBuilder对象封装到SearchSourceBuilder
sourceBuilder.query(queryBuilder);
/*
排序:
1、排序字段
2、排序规则(默认正排)
*/
sourceBuilder.sort("id", SortOrder.DESC);
/*
分页:
from: 起始索引位置 int start = (pageNum - 1)*pageSize
size; 页大小
*/
sourceBuilder.from(4);
sourceBuilder.size(4);
/*
高亮:
1.前置标签
2.后置标签
3.高亮字段
*/
HighlightBuilder highlightBuilder = new HighlightBuilder();
//前置标签
highlightBuilder.preTags("<span color='red'>");
//后置标签
highlightBuilder.postTags("<span>");
//高亮字段
highlightBuilder.field("title");
sourceBuilder.highlighter(highlightBuilder);
/*
source过滤---》作业
*/
//5.将SearchSourceBuilder封装到SearchRequest
searchRequest.source(sourceBuilder);
try {
//6.发送请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//7.解析结果
SearchHit[] hits = searchResponse.getHits().getHits();
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
System.out.println("查询结果: " + sourceAsString);
/*
高亮结果解析
*/
//获取高亮结果
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
//根据高亮字段获取结果
HighlightField title = highlightFields.get("title");
//遍历数组
Text[] fragments = title.getFragments();
for (Text fragment : fragments) {
System.out.println("高亮结果: " + fragment);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
//2.释放资源
@After
public void closeClient(){
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、Spring Date ES
1. 创建项目
步骤:
-
创建spring-data-es项目
- web/lombok/elasticsearch
-
修改配置文件
-
集群名称
-
节点信息
spring: data: elasticsearch: cluster-name: elasticsearch #集群名称 cluster-nodes: 127.0.0.1:9300 #节点端口信息 127.0.0.1:9301,127.0.0.1:9302,127.0.0.1:9303
-
-
创建实体类
@Data @AllArgsConstructor @NoArgsConstructor //,shards = 5 分片数量,默认值为5(6.X,7.X--->3), replicas = 1副本数量,默认值为1 //indexName: 索引库名称 type: 类型 @Document(indexName = "goods",type = "goods") public class Goods { /* 必须有id,这里的id是全局唯一的标识,等同于es中的“_id” */ @Id private Long id; /** * 标题 * type: 字段数据类型 * analyzer: 分词器类型 * index: 是否索引(默认值:true) * store: 是否独立存储(默认值:false) */ @Field(type = FieldType.Text,analyzer = "ik_max_word") private String title; /** * 分类 */ @Field(type = FieldType.Keyword) private String category; /** * 品牌 */ @Field(type = FieldType.Keyword) private String brand; /** * 价格 */ @Field(type = FieldType.Double) private Double price; /** * 图片地址 */ @Field(type = FieldType.Keyword,index = false) private String images; }
-
创建仓库
public interface GoodsRepository extends ElasticsearchRepository<Goods, Long> { }
2. 代码实现
GoodRepository.class
import com.itheima.pojo.Goods;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
/**
* <dl>
* <dd>描述: ~节点业务逻辑实现</dd>
* <dd>创建时间: 15:38 2020/7/25</dd>
* <dd>创建人: zz</dd>
* <dt>版本历史: </dt>
* <pre>
* Date Author Version Description
* ------------------------------------------------------------------
* 2020/7/25 guodong 1.0 1.0 Version
* </pre>
* </dl>
*/
public interface GoodRepository extends ElasticsearchRepository<Goods,Long> {
List<Goods> findByPriceBetween(Double fromPrice, Double toPrice);
}
application.yml
server:
port: 8081
spring:
application:
name: spring-boot-es
#配置es连接信息
data:
elasticsearch:
cluster-name: elasticsearch #集群名称
cluster-nodes: 127.0.0.1:9300 #节点信息 tcp端口
#192.168.200.128:9301,192.168.200.128:9302,192.168.200.128:9303
以上服务搭建好以后可以直接运行项目,项目在启动时springboot会自动检测当前索引库是否存在,不存在则自动创建
测试类
import com.itheima.pojo.Goods;
import com.itheima.repository.GoodsRepository;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
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.ArrayList;
import java.util.List;
import java.util.Optional;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringDataEsApplicationTests {
@Autowired
private GoodsRepository goodsRepository;
/**
* @Author: guodong
* @Date: 12:25 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 新增文档
*/
@Test
public void createDoc(){
//1.准备新增数据
Goods goods = new Goods(1l,"小米手机","手机","小米", 2699.00, "http://www.baidu.com");
//2.调用仓库保存
Goods save = goodsRepository.save(goods);
}
/**
* @Author: guodong
* @Date: 14:33 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 批量新增
*/
@Test
public void batchAddDoc(){
//1.准备新增数据
List<Goods> goodsList = new ArrayList<>();
for (long i = 2; i < 10; i++) {
Goods goods = new Goods(i,"小米手机" + i,"手机","小米", 2699.00 + i, "http://www.baidu.com");
goodsList.add(goods);
}
//2.调用仓库保存
Iterable<Goods> goods = goodsRepository.saveAll(goodsList);
for (Goods good : goods) {
System.out.println("批量新增结果: " + good);
}
}
/**
* @Author: guodong
* @Date: 14:39 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 根据id查询
*/
@Test
public void queryById(){
Optional<Goods> optional = goodsRepository.findById(1l);
//Iterable<Goods> all = goodsRepository.findAll(); //作业findAll
if(optional.isPresent()){ //true--->表示查询结果有值
Goods goods = optional.get();
System.out.println("查询结果: " + goods);
}
}
/**
* @Author: guodong
* @Date: 14:43 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 使用queryBuilder
*/
@Test
public void queryBuilder(){
QueryBuilder queryBuilder = QueryBuilders.termQuery("title", "小米");
Iterable<Goods> search = goodsRepository.search(queryBuilder);
for (Goods goods : search) {
System.out.println("查询结果:" + goods);
}
}
/**
* @Author: guodong
* @Date: 14:55 2020/9/25
* @Parms []
* @ReturnType: void
* @Description: 自定义查询(了解)
*
* 格式:
* findBy + 字段名称 + 关键字(And or between ....) + 字段名称 (参数列表)
* 参数列表需要注意必须与字段名顺序一致
*
* between: 范围查询包含首位。
*/
@Test
public void findByPrice(){
List<Goods> byPriceBetween = goodsRepository.findByPriceBetween(2699.00, 2703.00);
for (Goods goods : byPriceBetween) {
System.out.println("查询结果" + goods);
}
}
}