前言
这里是在代码里面整合的过程。提示:以下是本篇文章正文内容,下面案例可供参考
一、整合代码
1.1 创建工程,导入坐标
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>elasticsearch-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.6.8</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.6.8</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.24</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
1.2 创建索引
/**
* 创建一个索引
*/
@Test
public void createIndex() throws UnknownHostException {
// 1. 配置信息:集群名称
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2. 客户端
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
// 3. 通过 API 创建索引
client.admin().indices().prepareCreate("index-hello").get();
// 关闭资源
client.close();
}
![请添加图片描述](https://img-blog.csdnimg.cn/5bf0644591be47259ba839027505eec9.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5qmZ5a2Q5piv6JOd6Imy55qE,size_20,color_FFFFFF,t_70,g_se,x_16)
1.3 创建映射 mapping
/**
* 创建映射
*
* 格式
* "mappings" : {
* "article" : {
* "dynamic" : "false",
* "properties" : {
* "id" : { "type" : "string" },
* "content" : { "type" : "string" },
* "author" : { "type" : "string" }
* }
* }
* }
*/
@Test
public void setMapping() throws IOException, ExecutionException, InterruptedException {
// 1. 配置信息:集群名称
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2. 客户端
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
// 3. 创建映射
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.startObject("article")
.startObject("properties")
.startObject("id")
.field("type", "integer")
.field("store", "yes")
.endObject()
.startObject("title")
.field("type", "string")
.field("store", "yes")
.field("analyzer", "ik_smart")
.endObject()
.startObject("content")
.field("type", "string")
.field("store", "yes")
.field("analyzer", "ik_smart")
.endObject()
.endObject()
.endObject()
.endObject();
PutMappingRequest mapping = Requests.putMappingRequest("index-hello")
.type("article").source(builder);
client.admin().indices().putMapping(mapping).get();
// 关闭资源
client.close();
}
1.4 建立文档
1.4.1 XContentBuilder 建立文档
/**
* 创建文档
*/
@Test
public void createDocument01() throws IOException {
// 1. 配置信息:集群名称
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2. 客户端
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
// 3. 创建文档对象
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.field("id", "2")
.field("title", "北方入秋速度明显加快,对滴降温幅度达到10度22222")
.field("content", "阿联酋一架客机在牛玉机场被隔离,20名乘客VB诶隔离")
.endObject();
client.prepareIndex()
.setIndex("index-hello")
.setType("article")
.setId("2")
.setSource(builder)
.get();
// 关闭资源
client.close();
}
1.4.2 jackson 转实体
添加依赖坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.1</version>
</dependency>
Article.java 实体类:
package com.kkb.es;
public class Article {
private Integer id;
private String title;
private String content;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
测试代码:
/**
* jsckson 转行创建对象
*/
@Test
public void createDocument02() throws IOException {
// 1. 配置信息:集群名称
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2. 客户端
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
// 3. 创建 Article 对象
Article article = new Article();
article.setId(3);
article.setTitle("MH370坠毁在柬埔寨密林?中国一公司地调集10颗卫星前去拍摄!!!!");
article.setContent("警惕荒唐的死亡游戏,俄15岁少年输掉游戏后用电锯自杀!!!");
// 对象转 字符串
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(article);
// 创建对象
client.prepareIndex()
.setIndex("index-hello")
.setType("article")
.setId("3")
.setSource(json, XContentType.JSON)
.get();
// 关闭资源
client.close();
}
1.5 文档查询
在这之前,我先把公共方法放在这里,包括了测试类运行前创建连接客户端和后面的关闭,和一个查询展示内容的公共方法。会在最后放上全部代码文件。
@Before
public void before() throws UnknownHostException {
settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
}
@After
public void after() {
//关闭client
client.close();
}
// 查找方法
private void search(QueryBuilder queryBuilder) {
//执行查询得到
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(queryBuilder)
.get();
//处理结果
SearchHits searchHits = searchResponse.getHits();
System.out.println("总行数:" + searchHits.getTotalHits());
Iterator<SearchHit> it = searchHits.iterator();
while (it.hasNext()) {
SearchHit searchHit = it.next();
//source->document的json输出
System.out.println(searchHit.getSourceAsString());
System.out.println("---文档属性-----");
Map<String, Object> document = searchHit.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
}
1.5.1 termQuery
/**
* 查询测试
*/
@Test
public void testQueryByTerm() throws UnknownHostException {
//创建⼀个QueryBuilder对象
//参数1:要搜索的字段
//参数2:要搜索的关键词
// 查询的信息
QueryBuilder queryBuilder = QueryBuilders.termQuery("title", "职责");
//执行查询得到
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(queryBuilder)
.get();
//处理结果
SearchHits searchHits = searchResponse.getHits();
System.out.println("总行数:" + searchHits.getTotalHits());
Iterator<SearchHit> it = searchHits.iterator();
while (it.hasNext()) {
SearchHit searchHit = it.next();
//source->document的json输出
System.out.println(searchHit.getSourceAsString());
System.out.println("---文档属性-----");
Map<String, Object> document = searchHit.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
}
当我们查不到数据时,可以先通过网页 uri 对内容进行分词,看看一下我们的内容被分词成什么内容,根据内容进行适当的修改。
1.5.2 QueryString
@Test
public void testQueryByQueryString() throws Exception {
//构件queryBuilder
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("本能").defaultField("title");
search(queryBuilder);
}
1.5.3 MatchQuery
@Test
public void testQueryByMathQuery() throws Exception {
//构件queryBuilder
QueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "护士");
//执行查询得到
search(queryBuilder);
}
1.5.4 使⽤⽂档ID查询⽂档
@Test
public void testSearchById() throws Exception {
//创建一个client对象
//创建一个查询对象
QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("14", "19");
search(queryBuilder);
}
1.5.5 查询⽂档分页操作
@Test
public void testSearchByMathAll() throws Exception {
//创建一个client对象
//创建一个查询对象
QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
//执行查询得到
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(queryBuilder)
.setFrom(0)
.setSize(5)
.get();
//处理结果
SearchHits searchHits = searchResponse.getHits();
System.out.println("总行数:" + searchHits.getTotalHits());
Iterator<SearchHit> it = searchHits.iterator();
while (it.hasNext()) {
SearchHit searchHit = it.next();
//source->document的json输出
System.out.println(searchHit.getSourceAsString());
System.out.println("---文档属性-----");
Map<String, Object> document = searchHit.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
}
1.5.6 查询结果高亮显示
1.5.6.1 介绍
在进⾏关键字搜索时,搜索出的内容中的关键字会显⽰不同的颜⾊,称之为⾼亮。
百度搜索关键字 “IK分词” ,对应的颜色就不一样
1.5.6.2 ⾼亮显⽰的html分析
通过开发者⼯具查看⾼亮数据的html代码实现:
ElasticSearch可以对查询出的内容中关键字部分进⾏标签和样式的设置,但是你需要告诉ElasticSearch 使⽤什么标签对⾼亮关键字进⾏包裹
1.5.6.3 代码实现
@Test
public void testSearchByHighlight() throws Exception {
//创建一个查询对象
QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("职责", "title", "content");
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
highlightBuilder.field("content");
highlightBuilder.preTags("<em>");
highlightBuilder.postTags("</em>");
//执行查询得到
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(queryBuilder)
.highlighter(highlightBuilder)
.get();
//处理结果
SearchHits searchHits = searchResponse.getHits();
System.out.println("总行数:" + searchHits.getTotalHits());
Iterator<SearchHit> it = searchHits.iterator();
while (it.hasNext()) {
SearchHit searchHit = it.next();
//source->document的json输出
System.out.println("-----文档内容-------");
System.out.println(searchHit.getSourceAsString());
System.out.println("----高亮结果-----");
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
for (Map.Entry<String, HighlightField> entry : highlightFields.entrySet()) {
System.out.println(entry.getKey() + ":\t" + Arrays.toString(entry.getValue().getFragments()));
}
}
}
1.5.7 代码文件
ElasticSearchTest.java
package com.kkb.es;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.client.Requests;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Test;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutionException;
public class ElasticSearchTest {
/**
* 创建一个索引
*/
@Test
public void createIndex() throws UnknownHostException {
// 1. 配置信息:集群名称
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2. 客户端
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
// 3. 通过 API 创建索引
client.admin().indices().prepareCreate("index_hello").get();
// 关闭资源
client.close();
}
/**
* 创建映射
*
* 格式
* "mappings" : {
* "article" : {
* "dynamic" : "false",
* "properties" : {
* "id" : { "type" : "string" },
* "content" : { "type" : "string" },
* "author" : { "type" : "string" }
* }
* }
* }
*/
@Test
public void setMapping() throws IOException, ExecutionException, InterruptedException {
// 1. 配置信息:集群名称
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2. 客户端
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
// 3. 创建映射
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.startObject("article")
.startObject("properties")
.startObject("id")
.field("type", "integer")
.field("store", "yes")
.endObject()
.startObject("title")
.field("type", "string")
.field("store", "yes")
.field("analyzer", "ik_smart")
.endObject()
.startObject("content")
.field("type", "string")
.field("store", "yes")
.field("analyzer", "ik_smart")
.endObject()
.endObject()
.endObject()
.endObject();
PutMappingRequest mapping = Requests.putMappingRequest("index_hello")
.type("article").source(builder);
client.admin().indices().putMapping(mapping).get();
// 关闭资源
client.close();
}
/**
* 创建文档
*/
@Test
public void createDocument01() throws IOException {
// 1. 配置信息:集群名称
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2. 客户端
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
// 3. 创建文档对象
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.field("id", "2")
.field("title", "北方入秋速度明显加快,对滴降温幅度达到10度22222")
.field("content", "阿联酋一架客机在牛玉机场被隔离,20名乘客VB诶隔离")
.endObject();
client.prepareIndex()
.setIndex("index_hello")
.setType("article")
.setId("2")
.setSource(builder)
.get();
// 关闭资源
client.close();
}
/**
* jsckson 转行创建对象
*/
@Test
public void createDocument02() throws IOException {
// 1. 配置信息:集群名称
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2. 客户端
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
// 3. 创建 Article 对象
Article article = new Article();
article.setId(3);
article.setTitle("MH370坠毁在柬埔寨密林?中国一公司地调集10颗卫星前去拍摄!!!!");
article.setContent("警惕荒唐的死亡游戏,俄15岁少年输掉游戏后用电锯自杀!!!");
// 对象转 字符串
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(article);
// 创建对象
client.prepareIndex()
.setIndex("index_hello")
.setType("article")
.setId("3")
.setSource(json, XContentType.JSON)
.get();
// 关闭资源
client.close();
}
/**
* 批量添加数据,方便查询
*/
@Test
public void addBatchDocument() throws UnknownHostException, JsonProcessingException {
// 1. 配置信息
Settings settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
// 2.客户端
PreBuiltTransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
for (int i = 4; i < 100; i++) {
//创建⼀个Article对象
Article article = new Article();
//设置对象的属性
article.setId(i);
article.setTitle("⼥护⼠路遇昏迷男⼦跪地抢救:救⼈是职责更是本能" + i);
article.setContent("江⻄变质营养餐事件已致24⼈就医 多名官员被调查" + i);
//把article对象转换成json格式的字符串。
ObjectMapper objectMapper = new ObjectMapper();
String jsonDocument = objectMapper.writeValueAsString(article);
System.out.println(jsonDocument);
//使⽤client对象把⽂档写⼊索引库
client.prepareIndex("index_hello","article", i + "")
.setSource(jsonDocument, XContentType.JSON)
.get();
}
//关闭客户端
client.close();
}
}
IndexSearchTest.java
package com.kkb.es;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
public class IndexSearchTest {
Settings settings;
PreBuiltTransportClient client;
@Before
public void before() throws UnknownHostException {
settings = Settings.builder().put("cluster.name", "my-elasticsearch").build();
client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("192.168.198.100"), 9300));
}
@After
public void after() {
//关闭client
client.close();
}
/**
* 查询测试
*/
@Test
public void testQueryByTerm() throws UnknownHostException {
// 查询的信息
QueryBuilder queryBuilder = QueryBuilders.termQuery("title", "职责");
//执行查询得到
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(queryBuilder)
.get();
//处理结果
SearchHits searchHits = searchResponse.getHits();
System.out.println("总行数:" + searchHits.getTotalHits());
Iterator<SearchHit> it = searchHits.iterator();
while (it.hasNext()) {
SearchHit searchHit = it.next();
//source->document的json输出
System.out.println(searchHit.getSourceAsString());
System.out.println("---文档属性-----");
Map<String, Object> document = searchHit.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
}
@Test
public void testQueryByQueryString() throws Exception {
//构件queryBuilder
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("本能").defaultField("title");
search(queryBuilder);
}
private void search(QueryBuilder queryBuilder) {
//执行查询得到
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(queryBuilder)
.get();
//处理结果
SearchHits searchHits = searchResponse.getHits();
System.out.println("总行数:" + searchHits.getTotalHits());
Iterator<SearchHit> it = searchHits.iterator();
while (it.hasNext()) {
SearchHit searchHit = it.next();
//source->document的json输出
System.out.println(searchHit.getSourceAsString());
System.out.println("---文档属性-----");
Map<String, Object> document = searchHit.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
}
@Test
public void testQueryByMathQuery() throws Exception {
//构件queryBuilder
QueryBuilder queryBuilder = QueryBuilders.matchQuery("title", "职责");
//执行查询得到
search(queryBuilder);
}
@Test
public void testSearchById() throws Exception {
//创建一个client对象
//创建一个查询对象
QueryBuilder queryBuilder = QueryBuilders.idsQuery().addIds("14", "19");
search(queryBuilder);
}
@Test
public void testSearchByMathAll() throws Exception {
//创建一个client对象
//创建一个查询对象
QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
//执行查询得到
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(queryBuilder)
.setFrom(0)
.setSize(5)
.get();
//处理结果
SearchHits searchHits = searchResponse.getHits();
System.out.println("总行数:" + searchHits.getTotalHits());
Iterator<SearchHit> it = searchHits.iterator();
while (it.hasNext()) {
SearchHit searchHit = it.next();
//source->document的json输出
System.out.println(searchHit.getSourceAsString());
System.out.println("---文档属性-----");
Map<String, Object> document = searchHit.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
}
@Test
public void testSearchByHighlight() throws Exception {
//创建一个查询对象
QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery("职责", "title", "content");
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
highlightBuilder.field("content");
highlightBuilder.preTags("<em>");
highlightBuilder.postTags("</em>");
//执行查询得到
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(queryBuilder)
.highlighter(highlightBuilder)
.get();
//处理结果
SearchHits searchHits = searchResponse.getHits();
System.out.println("总行数:" + searchHits.getTotalHits());
Iterator<SearchHit> it = searchHits.iterator();
while (it.hasNext()) {
SearchHit searchHit = it.next();
//source->document的json输出
System.out.println("-----文档内容-------");
System.out.println(searchHit.getSourceAsString());
System.out.println("----高亮结果-----");
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
for (Map.Entry<String, HighlightField> entry : highlightFields.entrySet()) {
System.out.println(entry.getKey() + ":\t" + Arrays.toString(entry.getValue().getFragments()));
}
}
}
}
2 SpringData ElasticSearch
2.1 简介
3.1.1 Spring Data
Spring Data是⼀个⽤于简化数据库访问,并⽀持云服务的开源框架。其主要⽬标是使得对数据的访问变 得⽅便快捷,并⽀持map-reduce框架和云计算数据服务。 Spring Data可以极⼤的简化JPA的写法,可 以在⼏乎不⽤写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等⼀些 常⽤的功能
Spring Data 官网 https://spring.io/projects/spring-data
Spring Data常⽤的功能模块如下:
Spring Data ElasticSearch
Spring Data ElasticSearch 基于 spring data API 简化 elasticSearch操作,将原始操作elasticSearch的客 户端API 进⾏封装 。Spring Data为Elasticsearch项⽬提供集成搜索引擎。Spring Data Elasticsearch POJO的关键功能区域为中⼼的模型与Elastichsearch交互⽂档和轻松地编写⼀个存储库数据访问层。
官方网站 https://spring.io/projects/spring-data-elasticsearch
3.2 入门案例
3.2.1 pom.xml 文件
要注意的是 springboot的版本,一定不要太高,变动还是挺大的。
<?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.1.16.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>es-demo02</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>es-demo02</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-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.2.2 启动类
package com.example.esdemo02;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class EsDemo02Application {
public static void main(String[] args) {
SpringApplication.run(EsDemo02Application.class, args);
}
}
3.2.3 配置文件
spring:
data:
elasticsearch:
cluster-name: my-elasticsearch
cluster-nodes: 192.168.198.100:9300
3.2.4 实体类
package com.example.esdemo02.domain;
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;
@Document(indexName = "sjq_blog", type = "article")
public class Article {
@Id
@Field(type = FieldType.Long, store = true)
private long id;
@Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
private String title;
@Field(type = FieldType.Text, store = true, analyzer = "ik_smart")
private String content;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
3.2.5 dao 文件
package com.example.esdemo02.dao;
import com.example.esdemo02.domain.Article;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;
public interface ArticleDao extends ElasticsearchRepository<Article, Long> {
List<Article> findByTitleLike(String title);
List<Article> findByTitle(String title);
List<Article> findByTitleLikeOrContent(String title, String content);
List<Article> findByTitleOrContent(String title, String content, Pageable pageable);
}
3.2.6 测试
3.2.6.1 创建索引
如果要创建的索引不存在,那么我们代码执行时,会根据我们的注解信息,自动创建索引和 mapping,如果已经存在,我们也可以通过方法,将 mapping添加进去
@Test
public void createIndex() {
//创建索引,并配置映射关系(根据实体类中的注解信息创建)
template.createIndex(Article.class);
//配置映射关系(当我们的索引已存在,需要单独添加mapping时)
//template.putMapping(Article.class);
}
3.2.6.2 添加数据
/**
* 添加文档数据
*/
@Test
public void addDocument() throws Exception {
for (int i = 10; i <= 20; i++) {
//创建⼀个Article对象
Article article = new Article();
article.setId(i);
article.setTitle("⼥护⼠路遇昏迷男⼦跪地抢救:救⼈是职责更是本能" + i);
article.setContent("这是⼀个美丽的⼥护⼠妹妹" + i);
//把⽂档写⼊索引库
articleDao.save(article);
}
}
3.2.6.3 删除文档
/**
* 删除全部文档数据
*/
@Test
public void deleteDocumentById() throws Exception {
//全部删除
articleDao.deleteAll();
}
3.2.6.4 查询所有数据
/**
* 查询所有文档信息
*/
@Test
public void findAll() {
Iterable<Article> articles = articleDao.findAll();
articles.forEach(a-> System.out.println(a));
}
3.2.6.5 根据 id 查询
/**
* 根据 id 查询
*/
@Test
public void testFindById() throws Exception {
Optional<Article> optional = articleDao.findById(10l);
Article article = optional.get();
System.out.println(article);
}
3.2.6.6 根据内容查询
/**
* 根据内容查询
*/
@Test
public void testFindByTitle() throws Exception {
List<Article> list = articleDao.findByTitle("⼥护⼠");
list.stream().forEach(a -> System.out.println(a));
}
3.2.6.7 跨字段查询
/**
* 跨字段查询
*/
@Test
public void testFindByTitleOrContent() throws Exception {
Pageable pageable = PageRequest.of(1, 5);
articleDao.findByTitleOrContent("title", "⼥护⼠", pageable)
.forEach(a-> System.out.println(a));
}
3.2.6.8 对象查询
/**
* 对象查询:
*/
@Test
public void testNativeSearchQuery() throws Exception {
//创建⼀个查询对象
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.queryStringQuery("⼥护⼠").defaultField("title"))
.withPageable(PageRequest.of(0, 15))
.build();
//执⾏查询
List<Article> articleList = template.queryForList(query,
Article.class);
articleList.forEach(a-> System.out.println(a));
}
3.2.7 聚合查询
# 桶内度量
GET /car_index/car/_search
{
"query": {
"match_all": {}
},
"aggs": {
"group_by_bland": {
"terms": {
"field": "color"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
3.2.7.1
划分桶
@Test
public void testQuerySelfAggs(){
//查询条件的构建器
NativeSearchQueryBuilder queryBuilder = new
NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery());
//排除所有的字段查询,
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]
{},null));
//添加聚合条件
queryBuilder.addAggregation(AggregationBuilders.terms("group_by_color").field
("color"));
//执⾏查询,把查询结果直接转为聚合page
AggregatedPage<Car> aggPage = (AggregatedPage<Car>)
carDao.search(queryBuilder.build());
//从所有的聚合中获取对应名称的聚合
StringTerms agg = (StringTerms) aggPage.getAggregation("group_by_color");
//从聚合的结果中获取所有的桶信息
List<StringTerms.Bucket> buckets = agg.getBuckets();
for (StringTerms.Bucket bucket : buckets) {
String brand = bucket.getKeyAsString();
long docCount = bucket.getDocCount();
System.out.println("color = " + brand+" 总数:"+docCount);
}
}
桶内度量
@Test
public void testQuerySelfSubAggs(){
//查询条件的构建器
NativeSearchQueryBuilder queryBuilder = new
NativeSearchQueryBuilder().withQuery(QueryBuilders.matchAllQuery());
//排除所有的字段查询,
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]
{},null));
//添加聚合条件
queryBuilder.addAggregation(AggregationBuilders.terms("group_by_color").field
("color")
.subAggregation(AggregationBuilders.avg("avg_price").field("price")));
//执⾏查询,把查询结果直接转为聚合page
AggregatedPage<Car> aggPage = (AggregatedPage<Car>)
carDao.search(queryBuilder.build());
//从所有的聚合中获取对应名称的聚合
StringTerms agg = (StringTerms) aggPage.getAggregation("group_by_color");
//从聚合的结果中获取所有的桶信息
List<StringTerms.Bucket> buckets = agg.getBuckets();
for (StringTerms.Bucket bucket : buckets) {
String brand = bucket.getKeyAsString();
long docCount = bucket.getDocCount();
//取得内部聚合
InternalAvg avg = (InternalAvg)
bucket.getAggregations().asMap().get("avg_price");
System.out.println("brand = " + brand+" 总数:"+docCount+" 平均价格:"+avg.getValue());
}
}