ElasticSearch第二天
学习目标:
- 能够使用java客户端完成创建、删除索引的操作
- 能够使用java客户端完成文档的增删改的操作
- 能够使用java客户端完成文档的查询操作
- 能够完成文档的分页操作
- 能够完成文档的高亮查询操作
- 能够搭建Spring Data ElasticSearch的环境
- 能够完成Spring Data ElasticSearch的基本增删改查操作
- 能够掌握基本条件查询的方法命名规则
第一章 ElasticSearch编程操作
1.1 创建工程,导入坐标
pom.xml坐标
<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>
1.2 创建索引index
@Test
public void createIndex() throws Exception {
//创建一个Setings对象 相当于是一个配置信息,主要配置集群的名称
Settings build = Settings.builder()
.put("cluster.name","my-elasticsearch")
.build();
///创建一个客户端Client对象
TransportClient client = new PreBuiltTransportClient(build);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9301));
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9302));
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9303));
/// 创建client对象创建索引库 //执行操作
client.admin().indices().prepareCreate("index_hello").get();
//关闭client对象
client.close();
}
1.3 创建映射mapping
public void setMappings() throws Exception {
//创建一个Settings对象
Settings settings = Settings.builder()
.put("cluster.name", "my-elasticsearch")
.build();
///创建一个TransportClient对象
TransportClient client = new PreBuiltTransportClient(settings)
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9301))
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9302))
.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9303));
//创建一个Mappings信息
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
.startObject()
.startObject("article")
.startObject("properties")
.startObject("id")
.field("type","long")
.field("store",true)
.endObject()
.startObject("title")
.field("type","text")
.field("store",true)
.field("analyzer","ik_smart")
.endObject()
.startObject("content")
.field("type","text")
.field("store",true)
.field("analyzer","ik_smart")
.endObject()
.endObject()
.endObject()
.endObject();
//使用client把mapping信息设置到索引中
client.admin().indices()
//设置要做映射的索引
.preparePutMapping("index_hello")
//设置要做映射的type
.setType("article")
//mapping信息,可以是XContentBuilder对象也可以是字符串也可以是json格式
.setSource(xContentBuilder)
//执行操作
.get();
//关闭客户端
client.close();
}
1.4 建立文档document
1.4.1 建立文档(通过XContentBuilder)
//添加文档
@Test
public void testAddDocument() throws Exception {
//创建一个client对象
//创建一个文档对象
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
.startObject()
.field("id",1l)
.field("title","北方入秋速度明显加快,多地降温幅度最多可达10度")
.field("content","阿联酋一架客机在纽约基础被隔离,10名乘客病例")
.endObject();
//把文档对象添加到索引库
///设置索引名称 type 设置文档id,如果不设置的话自动的生成一个id 设置文档信息
client.prepareIndex("index_hello","article","1").setSource(xContentBuilder).get();
//关闭客户端
client.close();
}
1.4.2 建立文档(使用Jackson转换实体)
1)创建Article实体
public class Article {
private Integer id;
private String title;
private String content;
getter/setter...
}
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>
@Test
public void testAddDocument2() throws Exception {
///创建Article对象
Article article = new Article();
//设置对象的属性
article.setId(3);
article.setTitle("MH370坠毁在柬埔寨密林?");
article.setContent("警惕荒唐的死亡游戏!饿15岁少年");
//把article对象转换成json格式的字符串
ObjectMapper objectMapper = new ObjectMapper();
String jsonDocument = objectMapper.writeValueAsString(article);
System.out.println(jsonDocument);
//关闭客户端
client.prepareIndex("index_hello","article","3").setSource(jsonDocument, XContentType.JSON).get();
client.close();
}
1.5 查询文档操作
2.5.2 使用文档ID查询文档
@Test
public void testSearchById() throws Exception {
// 创建一个client对象
//创建一个查询对象
QueryBuilder QueryBuilder = QueryBuilders.idsQuery().addIds("1","2");
//执行查询
SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(QueryBuilder).get();
//取查询结果
SearchHits hits = searchResponse.getHits();
//取查询结果的总记录数
System.out.println("查询结果总记录数:"+hits.getTotalHits());
//查询结果列表
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()){
SearchHit next = iterator.next();
//打印文档对象,以json格式输出
System.out.println(next.getSourceAsString());
//取文档的属性
System.out.println("文档的属性");
Map<String,Object> document = next.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
//关闭client
client.close();
}
1.5.1关键词查询
@Test
public void testQueryByTerm() throws Exception{
///创建一个QueryBuilder对象
// name 要搜索的字段 value 要搜索的关键词
QueryBuilder queryBuilder = QueryBuilders.termQuery("title","北方");
search(queryBuilder);
}
2.5.2 字符串查询
@Test
public void testQueryStringQuery() throws Exception{
//创建一个QueryBuilder对象
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(“速度与激情”).defaultField(“title”); //默认搜索域 defaultField
search(queryBuilder);
}
2.6.2 分页查询
@Test
public void testQueryStringQuery1() throws Exception{
//创建一个QueryBuilder对象
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("打算").defaultField("title"); //默认搜索域 defaultField
search1(queryBuilder);
}
2.7 查询结果高亮操作
2.7.1 什么是高亮显示
在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮
百度搜索关键字"传智播客"
京东商城搜索"笔记本"
2.7.2 高亮显示的html分析
通过开发者工具查看高亮数据的html代码实现:
ElasticSearch可以对查询出的内容中关键字部分进行标签和样式的设置,但是你需要告诉ElasticSearch使用什么标签对高亮关键字进行包裹
2.7.3 高亮显示代码实现
//设置高亮显示
@Test
public void testQueryStringQuery3() throws Exception{
//创建一个QueryBuilder对象
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(“打算”).defaultField(“title”); //默认搜索域 defaultField
search2(queryBuilder,“title”);
}
整体代码
package com.itheima.es;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
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.index.query.IdsQueryBuilder;
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.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.net.InetAddress;
import java.util.Iterator;
import java.util.Map;
public class ElasticSearchClientTest {
private TransportClient client;
@Before
public void init() throws Exception {
//创建一个Setings对象 相当于是一个配置信息,主要配置集群的名称
Settings build = Settings.builder()
.put("cluster.name","my-elasticsearch")
.build();
///创建一个客户端Client对象
client = new PreBuiltTransportClient(build);
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9301));
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9302));
client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9303));
}
@Test
public void createIndex() throws Exception {
创建一个Setings对象 相当于是一个配置信息,主要配置集群的名称
//Settings build = Settings.builder()
// .put("cluster.name","my-elasticsearch")
// .build();
/创建一个客户端Client对象
//TransportClient client = new PreBuiltTransportClient(build);
//client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9301));
//client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9302));
//client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9303));
/// 创建client对象创建索引库 //执行操作
client.admin().indices().prepareCreate("index_hello").get();
//关闭client对象
client.close();
}
@Test
public void setMappings() throws Exception {
//创建一个Settings对象
//Settings settings = Settings.builder()
// .put("cluster.name", "my-elasticsearch")
// .build();
/创建一个TransportClient对象
//TransportClient client = new PreBuiltTransportClient(settings)
// .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9301))
// .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9302))
// .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"),9303));
//创建一个Mappings信息
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
.startObject()
.startObject("article")
.startObject("properties")
.startObject("id")
.field("type","long")
.field("store",true)
.endObject()
.startObject("title")
.field("type","text")
.field("store",true)
.field("analyzer","ik_smart")
.endObject()
.startObject("content")
.field("type","text")
.field("store",true)
.field("analyzer","ik_smart")
.endObject()
.endObject()
.endObject()
.endObject();
//使用client把mapping信息设置到索引中
client.admin().indices()
//设置要做映射的索引
.preparePutMapping("index_hello")
//设置要做映射的type
.setType("article")
//mapping信息,可以是XContentBuilder对象也可以是字符串也可以是json格式
.setSource(xContentBuilder)
//执行操作
.get();
//关闭客户端
client.close();
}
//添加文档
@Test
public void testAddDocument() throws Exception {
//创建一个client对象
//创建一个文档对象
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
.startObject()
.field("id",2l)
.field("title","北方入秋速度明显加快,多地降温幅度最多可达10度22222")
.field("content","阿联酋一架客机在纽约基础被隔离,10名乘客病例")
.endObject();
//把文档对象添加到索引库
///设置索引名称 type 设置文档id,如果不设置的话自动的生成一个id 设置文档信息
client.prepareIndex("index_hello","article","2").setSource(xContentBuilder).get();
//关闭客户端
client.close();
}
@Test
public void testAddDocument2() throws Exception {
///创建Article对象
Article article = new Article();
//设置对象的属性
article.setId(3);
article.setTitle("MH370坠毁在柬埔寨密林?");
article.setContent("警惕荒唐的死亡游戏!饿15岁少年");
//把article对象转换成json格式的字符串
ObjectMapper objectMapper = new ObjectMapper();
String jsonDocument = objectMapper.writeValueAsString(article);
System.out.println(jsonDocument);
//关闭客户端
client.prepareIndex("index_hello","article","3").setSource(jsonDocument, XContentType.JSON).get();
client.close();
}
@Test
public void testAddDocument3() throws Exception {
for (int i = 4; i < 100; i++) {
///创建Article对象
Article article = new Article();
//设置对象的属性
article.setId(i);
article.setTitle("成龙阿萨德阿达撒打算打是的撒是的撒"+i);
article.setContent("成龙阿萨德阿达撒打算打是的撒是的撒"+i);
//把article对象转换成json格式的字符串
ObjectMapper objectMapper = new ObjectMapper();
String jsonDocument = objectMapper.writeValueAsString(article);
System.out.println(jsonDocument);
//关闭客户端
client.prepareIndex("index_hello","article",i+"").setSource(jsonDocument, XContentType.JSON).get();
}
client.close();
}
private void search(QueryBuilder QueryBuilder) throws Exception {
//执行查询
SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(QueryBuilder).get();
//取查询结果
SearchHits hits = searchResponse.getHits();
//取查询结果的总记录数
System.out.println("查询结果总记录数:"+hits.getTotalHits());
//查询结果列表
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()){
SearchHit next = iterator.next();
//打印文档对象,以json格式输出
System.out.println(next.getSourceAsString());
//取文档的属性
System.out.println("文档的属性");
Map<String,Object> document = next.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
//关闭client
client.close();
}
private void search1(QueryBuilder QueryBuilder) throws Exception {
//执行查询 设置分页信息
SearchResponse searchResponse = client.prepareSearch("index_hello").setTypes("article").setQuery(QueryBuilder).setFrom(0).setSize(5).get();
//取查询结果
SearchHits hits = searchResponse.getHits();
//取查询结果的总记录数
System.out.println("查询结果总记录数:"+hits.getTotalHits());
//查询结果列表
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()){
SearchHit next = iterator.next();
//打印文档对象,以json格式输出
System.out.println(next.getSourceAsString());
//取文档的属性
System.out.println("文档的属性");
Map<String,Object> document = next.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
}
//关闭client
client.close();
}
private void search2(QueryBuilder QueryBuilder, String highlightFiled) throws Exception {
HighlightBuilder highlightBuilder = new HighlightBuilder();
//高亮显示的字段
highlightBuilder.field("title");
highlightBuilder.preTags("<em>");
highlightBuilder.postTags("</em>");
//执行查询 设置分页信息
SearchResponse searchResponse = client.prepareSearch("index_hello")
.setTypes("article")
.setQuery(QueryBuilder)
.setFrom(0)
.setSize(5)
//设置高亮信息
.highlighter(highlightBuilder)
.get();
//取查询结果
SearchHits hits = searchResponse.getHits();
//取查询结果的总记录数
System.out.println("查询结果总记录数:"+hits.getTotalHits());
//查询结果列表
Iterator<SearchHit> iterator = hits.iterator();
while (iterator.hasNext()){
SearchHit next = iterator.next();
//打印文档对象,以json格式输出
System.out.println(next.getSourceAsString());
//取文档的属性
System.out.println("文档的属性");
Map<String,Object> document = next.getSource();
System.out.println(document.get("id"));
System.out.println(document.get("title"));
System.out.println(document.get("content"));
System.out.println("*************");
Map<String, HighlightField> highlightFields = next.getHighlightFields();
System.out.println(highlightFields); //{title=[title], fragments[[成龙阿萨德阿达撒<em>打算</em>打是的撒是的撒4]]}
//取高亮显示的结果
HighlightField field = highlightFields.get(highlightFiled);
Text[] fragments = field.getFragments();
if (fragments !=null){
String title = fragments[0].toString();
System.out.println(title);
}
}
//关闭client
client.close();
}
@Test
public void testSearchById() throws Exception {
// 创建一个client对象
//创建一个查询对象
QueryBuilder QueryBuilder = QueryBuilders.idsQuery().addIds("1","2");
search(QueryBuilder);
}
@Test
public void testQueryByTerm() throws Exception{
///创建一个QueryBuilder对象
// name 要搜索的字段 value 要搜索的关键词
QueryBuilder queryBuilder = QueryBuilders.termQuery("title","北方");
search(queryBuilder);
}
@Test
public void testQueryStringQuery() throws Exception{
//创建一个QueryBuilder对象
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("速度与激情").defaultField("title"); //默认搜索域 defaultField
search(queryBuilder);
}
@Test
public void testQueryStringQuery1() throws Exception{
//创建一个QueryBuilder对象
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("打算").defaultField("title"); //默认搜索域 defaultField
search1(queryBuilder);
}
//设置高亮显示
@Test
public void testQueryStringQuery3() throws Exception{
//创建一个QueryBuilder对象
QueryBuilder queryBuilder = QueryBuilders.queryStringQuery("打算").defaultField("title"); //默认搜索域 defaultField
search2(queryBuilder,"title");
}
}