因为es用的是6.8版本,对应springboot2.2.x版本,创建项目后修改pom文件
2.2.4.RELEASE
引入es依赖
org.elasticsearch.client elasticsearch-rest-high-level-client6.8.18
在配置文件中添加
# es服务地址 elasticsearch.host=127.0.0.1 # es服务端口 elasticsearch.port=9200 # 配置日志级别,开启debug日志 logging.level.com.atguigu.es=debug
编写es配置类
package com.lzq.config;
import lombok.Data;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration //配置类,启动就会加载
@ConfigurationProperties(prefix = "elasticsearch") //读取配置文件中带前缀的值
@Component
@Data //安装Lombok插件
public class ElasticSearchConfig {
private String host ;
private Integer port ;
@Bean
public RestHighLevelClient client(){
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
return restHighLevelClient;
}
}
测试
@SpringBootTest
class DemoApplicationTests {
@Autowired
private RestHighLevelClient client;
@Test
public void create() throws IOException {
//1.创建请求对象,创建索引的请求
CreateIndexRequest request = new CreateIndexRequest("shopping1");
//2.客户端发送请求,获取响应对象
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
//3.打印响应对象中的返回结果
//返回index信息
System.out.println("index:" + response.index());
//acknowledged代表创建成功
System.out.println("acknowledged:" + response.isAcknowledged());
//4.关闭客户端,释放连接资源
client.close();
}
//查看索引库
@Test
public void getIndex() throws IOException {
//1.创建请求对象:查询索引库
GetIndexRequest request = new GetIndexRequest("shopping1");
//2.客户端执行请求发送,返回响应对象
GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
//3.打印结果信息
System.out.println("aliases:"+response.getAliases());
System.out.println("mappings:"+response.getMappings());
System.out.println("settings:"+response.getSettings());
//4.关闭客户端,释放连接资源
client.close();
}
//删除索引库
@Test
public void deleteIndex() throws IOException {
//1.创建请求对象
DeleteIndexRequest request = new DeleteIndexRequest("shopping1");
//2.客户端发送请求,获取响应对象
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
//3.打印结果信息
System.out.println("ack:" + response.isAcknowledged());
//4.关闭客户端,释放连接资源
client.close();
}
}
配置映射
1.配置映射,一共2种方式:
第一种:使用XContentBuilder,构建请求体
第二种:使用JSON字符串
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetMappingsRequest;
import org.elasticsearch.client.indices.GetMappingsResponse;
import org.elasticsearch.client.indices.PutMappingRequest;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
@SpringBootTest
class EsDemo2 {
@Autowired
private RestHighLevelClient client;
@Test
public void putMapping01() throws IOException {
//1.创建请求对象:配置映射
PutMappingRequest request = new PutMappingRequest("shopping1");
//构建请求体
XContentBuilder jsonBuilder = XContentFactory.jsonBuilder();
jsonBuilder.startObject()
.startObject("properties")
.startObject("title")
.field("type", "text").field("analyzer", "ik_max_word")
.endObject()
.startObject("subtitle")
.field("type", "text").field("analyzer", "ik_max_word")
.endObject()
.startObject("images")
.field("type", "keyword").field("index", false)
.endObject()
.startObject("price")
.field("type", "float")
.endObject()
.endObject()
.endObject();
//设置请求体,source("请求体json构建器对象");
request.source(jsonBuilder);
//2.客户端发送请求,获取响应对象
AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
//3.打印响应结果
System.out.println("acknowledged::" + response.isAcknowledged());
}
@Test
public void putMapping02() throws IOException {
//1.创建请求对象:配置映射
PutMappingRequest request = new PutMappingRequest("shopping1");
//设置请求体,source("请求体json字符串","请求体的数据类型");
request.source("{"properties":{"title":{"type":"text","analyzer":"ik_max_word"},"subtitle":{"type":"text","analyzer":"ik_max_word"},"price":{"type":"float"},"images":{"type":"keyword","index":false}}}", XContentType.JSON);
//2.客户端发送请求,获取响应对象
AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
//3.打印响应结果
System.out.println("acknowledged::" + response.isAcknowledged());
}
@Test
public void getMapping() throws IOException {
//1.创建请求对象:查看映射
GetMappingsRequest request = new GetMappingsRequest();
//设置索引库name
request.indices("shopping1");
//2.客户端发送请求,获取响应对象
GetMappingsResponse response = client.indices().getMapping(request, RequestOptions.DEFAULT);
//3.打印响应结果
System.out.println("mappings::" + response.mappings());
System.out.println("Source::" + response.mappings().get("shopping1").getSourceAsMap());
}
}
文档操作
//新增文档
@Test
public void saveDoc() throws IOException {
//1.创建请求对象(创建索引库CreateIndexRequest),索引库名称、类型名称、主键id
IndexRequest request = new IndexRequest().index("shopping").type("_doc").id("2");
//方式1:写一个Product对象将对象转为json字符串
// Product product = Product.builder().id(1L).title("小米手机").price(1999.0).build();
// ObjectMapper objectMapper = new ObjectMapper();
// String productJson = objectMapper.writevalueAsString(product);
// request.source(productJson,XContentType.JSON);
//方式2:直接在source中写入key-value参数
request.source(XContentType.JSON, "id", "2","title", "小米手机", "price", "3999");
//2.客户端发送请求,获取响应对象
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
3.打印结果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_type:" + response.getType());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());
}
修改文档*
public void update() throws IOException {
//1.创建请求对象(创建索引库CreateIndexRequest),索引库名称、类型名称、主键id
UpdateRequest request = new UpdateRequest().index("shopping").type("_doc").id("2");
//设置请求体
request.doc(XContentType.JSON, "id", "2", "title", "小米手机", "price", "2999");
//2.客户端发送请求,获取响应对象
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
3.打印结果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_type:" + response.getType());
System.out.println("_id:" + response.getId());
System.out.println("_result:" + response.getResult());
}
//查询文档
@Test
public void getDoc() throws IOException {
//1.创建请求对象
GetRequest request = new GetRequest().index("shopping").type("_doc").id("2");
//2.客户端发送请求,获取响应对象
GetResponse response = client.get(request, RequestOptions.DEFAULT);
3.打印结果信息
System.out.println("_index:" + response.getIndex());
System.out.println("_type:" + response.getType());
System.out.println("_id:" + response.getId());
System.out.println("source:" + response.getSourceAsString());
}
//删除文档
@Test
public void deleteDoc() throws IOException {
//创建请求对象
DeleteRequest request = new DeleteRequest().index("shopping").type("_doc").id("2");
//客户端发送请求,获取响应对象
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
//打印信息
System.out.println(response.toString());
}
//批量新增操作
@Test
public void bulkSave() throws IOException {
//创建请求对象
BulkRequest request = new BulkRequest();
request.add(new IndexRequest().index("shopping").type("_doc").id("1").source(XContentType.JSON, "title", "小米手机"));
request.add(new IndexRequest().index("shopping").type("_doc").id("2").source(XContentType.JSON, "title", "苹果手机"));
request.add(new IndexRequest().index("shopping").type("_doc").id("3").source(XContentType.JSON, "title", "华为手机"));
//客户端发送请求,获取响应对象
BulkResponse responses = client.bulk(request, RequestOptions.DEFAULT);
//打印结果信息
System.out.println("took:" + responses.getTook());
System.out.println("items:" + responses.getItems());
}
//批量删除操作
@Test
public void bulkDelete() throws IOException {
//创建请求对象
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest().index("shopping").type("_doc").id("1"));
request.add(new DeleteRequest().index("shopping").type("_doc").id("2"));
request.add(new DeleteRequest().index("shopping").type("_doc").id("3"));
//客户端发送请求,获取响应对象
BulkResponse responses = client.bulk(request, RequestOptions.DEFAULT);
//打印结果信息
System.out.println("took:" + responses.getTook());
System.out.println("items:" + responses.getItems());
}
}
请求体查询
@SpringBootTest
class EsDemo3 {
@Autowired
private RestHighLevelClient client;
@Test
public void initData() throws IOException {
//批量新增操作
BulkRequest request = new BulkRequest();
request.add(new IndexRequest().type("_doc").index("shopping01").source(XContentType.JSON, "title", "小米手机", "images", "http://www.gulixueyuan.com/xm.jpg", "price", 1999.0));
request.add(new IndexRequest().type("_doc").index("shopping01").source(XContentType.JSON, "title", "小米电视", "images", "http://www.gulixueyuan.com/xmds.jpg", "price", 2999.0));
request.add(new IndexRequest().type("_doc").index("shopping01").source(XContentType.JSON, "title", "华为手机", "images", "http://www.gulixueyuan.com/hw.jpg", "price", 4999.0, "subtitle", "小米"));
request.add(new IndexRequest().type("_doc").index("shopping01").source(XContentType.JSON, "title", "apple手机", "images", "http://www.gulixueyuan.com/appletl.jpg", "price", 5999.00));
request.add(new IndexRequest().type("_doc").index("shopping01").source(XContentType.JSON, "title", "apple", "images", "http://www.gulixueyuan.com/apple.jpg", "price", 3999.00));
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println("took::" + response.getTook());
System.out.println("Items::" + response.getItems());
}
//请求体查询-基本查询
//1.创建请求对象
//2.客户端发送请求,获取响应对象
//3.打印结果信息
@Test
public void basicQuery() throws IOException {
//1.创建请求对象
SearchRequest request = new SearchRequest().indices("shopping01").types("_doc");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有
//sourceBuilder.query(QueryBuilders.matchAllQuery());//
//match查询,带分词器的查询
//sourceBuilder.query(QueryBuilders.matchQuery("title","小米手机").operator(Operator.AND));
//term查询:不带分词器,查询条件作为关键词
sourceBuilder.query(QueryBuilders.termQuery("price", "1999"));
//TODO ...multi_match:多个字段的match查询
//TODO ...terms查询:多个关键词去匹配
request.source(sourceBuilder);
//2.客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//3.打印结果信息
printResult(response);
}
private void printResult(SearchResponse response) {
SearchHits hits = response.getHits();
System.out.println("took:" + response.getTook());
System.out.println("timeout:" + response.isTimedOut());
System.out.println("total:" + hits.getTotalHits());
System.out.println("MaxScore:" + hits.getMaxScore());
System.out.println("hits========>>");
for (SearchHit hit : hits) {
//输出每条查询的结果信息
System.out.println(hit.getSourceAsString());
}
System.out.println("<<========");
}
@Test
public void fetchSourceAndSortAndByPage() throws IOException {
//1.创建请求对象
SearchRequest request = new SearchRequest().indices("shopping01").types("_doc");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询所有
sourceBuilder.query(QueryBuilders.matchAllQuery());
//分页信息
//当前页其实索引(第一条数据的顺序号),from
sourceBuilder.from(2);
//每页显示多少条size
sourceBuilder.size(2);
//排序信息,参数一:排序的字段,参数二:顺序ASC升序,降序DESC
sourceBuilder.sort("price", SortOrder.ASC);
//查询字段过滤
String[] excludes = {};
String[] includes = {"title", "subtitle", "price"};
sourceBuilder.fetchSource(includes, excludes);
request.source(sourceBuilder);
//2.客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//3.打印结果信息
printResult(response);
}
@Test
public void boolAndRangeAndFuzzyQuery() throws IOException {
//1.创建请求对象
SearchRequest request = new SearchRequest().indices("shopping01").types("_doc");
//构建查询的请求体
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//高级查询的三种方式:
//-----------------------------------------------------------------------------
// //bool查询:查询title中必须包含小米,一定不含有电视,应该含有手机的所有商品
// BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// //must
// boolQueryBuilder.must(QueryBuilders.matchQuery("title", "小米"));
// //must not
// boolQueryBuilder.mustNot(QueryBuilders.matchQuery("title", "电视"));
// //should
// boolQueryBuilder.should(QueryBuilders.matchQuery("title", "手机"));
// sourceBuilder.query(boolQueryBuilder);
//-----------------------------------------------------------------------------
//范围查询:查询价格大于3千,小于5千的所有商品
// RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("price");
// //#### gt 大于(greater than)
// rangeQuery.gt("3000");
// //#### lt 小于(less than)
// rangeQuery.lt("5000");
// //#### gte 大于等于(greater than equals)
// //#### lte 小于等于(less than equals)
// sourceBuilder.query(rangeQuery);
//-----------------------------------------------------------------------------
//模糊查询:查询包含apple关键词的所有商品,完成模糊查询cpple
sourceBuilder.query(QueryBuilders.fuzzyQuery("title","cpple").fuzziness(Fuzziness.ONE));
//-----------------------------------------------------------------------------
request.source(sourceBuilder);
//2.客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//3.打印结果信息
printResult(response);
}
}
高亮查询
@Test
public void highLighterQuery() throws IOException {
//1.创建请求对象
SearchRequest request = new SearchRequest().types("_doc").indices("shopping01");
//2.创建查询请求体构建器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//构建查询方式:高亮查询
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("title","apple");
//设置查询方式
sourceBuilder.query(termsQueryBuilder);
//构建高亮字段
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("");//设置标签前缀
highlightBuilder.postTags("");//设置标签后缀
highlightBuilder.field("title");//设置高亮字段
//设置高亮构建对象
sourceBuilder.highlighter(highlightBuilder);
//设置请求体
request.source(sourceBuilder);
//3.客户端发送请求,获取响应对象
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//4.打印响应结果
SearchHits hits = response.getHits();
System.out.println("took::"+response.getTook());
System.out.println("time_out::"+response.isTimedOut());
System.out.println("total::"+hits.getTotalHits());
System.out.println("max_score::"+hits.getMaxScore());
System.out.println("hits::::>>");
for (SearchHit hit : hits) {
String sourceAsString = hit.getSourceAsString();
System.out.println(sourceAsString);
//打印高亮结果
Map highlightFields = hit.getHighlightFields();
System.out.println(highlightFields);
}
System.out.println("<<::::");
}
SpringData整合ES
创建项目加入依赖
org.projectlombok lombok org.springframework.boot spring-boot-starter-data-elasticsearch
编写配置文件
# es服务地址 elasticsearch.host=127.0.0.1 # es服务端口 elasticsearch.port=9200 # 配置日志级别,开启debug日志 logging.level.com.atguigu.es=debug
创建实体类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Product {
private Long id;//商品唯一标识
private String title;//商品名称
private String category;//分类名称
private Double price;//商品价格
private String images;//图片地址
}
创建配置类
import lombok.Data;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchEntityMapper;
import org.springframework.data.elasticsearch.core.EntityMapper;
@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
@Data
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
private String host ;
private Integer port ;
//重写父类方法
@Override
public RestHighLevelClient elasticsearchClient() {
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
return restHighLevelClient;
}
}
dao层
import com.lzq.pojo.Product; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.stereotype.Repository; @Repository public interface ProductDao extends ElasticsearchRepository{ }
修改实体类对应
@document(indexName = "shopping", type = "product", shards = 5, replicas = 1)
public class Product implements Serializable {
//必须有id,这里的id是全局唯一的标识,等同于es中的"—id"
@Id
private Long id;//商品唯一标识
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;//商品名称
@Field(type = FieldType.Keyword)
private String category;//分类名称
@Field(type = FieldType.Double)
private Double price;//商品价格
@Field(type = FieldType.Keyword, index = false)
private String images;//图片地址
}
测试
//注入ElasticsearchRestTemplate
@Autowired
private ElasticsearchRestTemplate elasticsearchRestTemplate;
//创建索引并增加映射配置
@Test
public void createIndex(){
//创建索引
boolean index = elasticsearchRestTemplate.createIndex(Product.class);
System.out.println("index = " + index);
index = elasticsearchRestTemplate.putMapping(Product.class);
System.out.println("index = " + index);
}
//删除索引
@Test
public void deleteIndex(){
boolean index = elasticsearchRestTemplate.deleteIndex(Product.class);
System.out.println("index = " + index);
}
测试:文档操作
注入dao层
@Autowired
private ProductDao productDao;
@Test
public void save(){
Product product = new Product();
product.setId(1L);
product.setTitle("小米手机");
product.setCategory("手机");
product.setPrice(1999.0);
product.setImages("http://www.gulixueyuan/xm.jpg");
productDao.save(product);
}
//修改
@Test
public void update(){
Product product = new Product();
product.setId(1L);
product.setTitle("小米2手机");
product.setCategory("手机");
product.setPrice(9999.0);
product.setImages("http://www.gulixueyuan/xm.jpg");
productDao.save(product);
}
//根据id查询
@Test
public void findById(){
Product product = productDao.findById(1L).get();
System.out.println(product);
}
//查询所有
@Test
public void findAll(){
Iterable products = productDao.findAll();
for (Product product : products) {
System.out.println(product);
}
}
//删除
@Test
public void delete(){
Product product = new Product();
product.setId(1L);
productDao.delete(product);
}
//批量新增
@Test
public void saveAll(){
List productList = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Product product = new Product();
product.setId(Long.valueOf(i));
product.setTitle("["+i+"]小米手机");
product.setCategory("手机");
product.setPrice(1999.0+i);
product.setImages("http://www.gulixueyuan/xm.jpg");
productList.add(product);
}
productDao.saveAll(productList);
}
//分页查询
@Test
public void findByPageable(){
//设置排序(排序方式,正序还是倒序,排序的id)
Sort sort = Sort.by(Sort.Direction.DESC,"id");
int currentPage=1;//当前页,第一页从0开始,1表示第二页
int pageSize = 20;//每页显示多少条
//设置查询分页
PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);
//分页查询
Page productPage = productDao.findAll(pageRequest);
System.out.println(productPage);
}
自定义DAO查询
| 关键字 | 命名规则 | 解释 | 示例 |
|---|---|---|---|
| and | findByField1AndField2 | 根据Field1和Field2获得数据 | findByTitleAndPrice |
| or | findByField1OrField2 | 根据Field1或Field2获得数据 | findByTitleOrPrice |
| is | findByField | 根据Field获得数据 | findByTitle |
| not | findByFieldNot | 根据Field获得补集数据 | findByTitleNot |
| between | findByFieldBetween | 获得指定范围的数据 | findByPriceBetween |
| lessThanEqual | findByFieldLessThan | 获得小于等于指定值的数据 | findByPriceLessThan |
@Test
public void findAllByTitleAndPrice(){
String title = "小米";
Double price = 2050.0;
List products = productDao.findByTitleAndPrice(title, price);
for (Product product : products) {
System.out.println(product);
}
}
@Test
public void findPriceBetween(){
double lowPrice = 2000.0;//最低价
double highPrice = 2005.0;//最高价
List products = productDao.findByPriceBetween(lowPrice, highPrice);
for (Product product : products) {
System.out.println(product);
}
}
只需要在dao层实现就行,不用自己写逻辑



