ElasticeSearch用法(使用Transport操作ES服务器),增删改查和批量操作
1、Lucene
单独使用Lucene实现站内搜索需要开发的工作量较大,主要表现在:索引维护、索引性能优化、搜索性能优化等,因此不建议采用。
2、Solr
Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。
Solr可以独立运行,运行在Tomcat、Jetty等这些Servlet容器中,Solr 索引的实现方法很简单,用 POST 方法向 Solr服务器发送一个描述 Field 及其内容的 XML 文档,Solr根据xml文档添加、删除、更新索引 。Solr 搜索只需要发送HTTP GET 请求,然后对 Solr 返回Xml、json等格式的查询结果进行解析,组织页面布局。Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。
3、Elasticsearch
Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可
以扩展到上百台服务器,处理PB级别的数据。
核心:
1、数据存储 海量 实时
2、数据检索、实时
ElasticSearch初体验
搭建ElasticSearch服务器
- 基于Docker搭建ES服务器 端口号:9200
- 基于Docker搭建ES-Head 可视化网页 端口号:9100
- 客户端进行连接ElasticSearch的时候 端口号为:9300
ElasticSearch数据模型
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引(Index) ⇒ 类型(type) ⇒ 文档(Docments) ⇒ 字段(Fields)
ElasticSearch存储的核心
索引:存储数据的对象 类是数据库中的数据库,可以存储多种类型的数据
类型:数据的类型 类是之前数据库中表
id:数据的唯一值
source:存储的内容,一般都是JSON字符串
Java操作ES服务器有两种方式
- ES的客户端 Transport
- Spring Dat Elasticsearch
Spring Data 系列:Spring给出的操作一切数据的框架
- Spring Data JPA
- Spring Data Redis
- Spring Data ElasticSearch
存储数据:
1、数据库 关系型数据库
Mysql Oracle
2、NO-SQL数据库
Redis
3、全文检索技术(搜索引擎技术)
ElasticSearch
代码实现
1、依赖Jar(Transport)的依赖
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch-x-content</artifactId>
<version>6.5.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>6.5.4</version>
</dependency>
2、代码实现
1、创建设置对象 指定集群名称
2、设置服务器地址 创建客户端对象
3、实现操作 增删改查
4、关闭销毁
基于Transport代码实现基本操作
基于Transport代码实现新增和修改(prepareIndex)
/**
* 基于Transport代码实现新增和修改
*/
public class Transport_Main{
public static void main(String[] args) {
//1、创建设置对象
Settings settings=Settings.builder().put("集群key","集群名称").build();
//创建来创建对象
Client client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(new InetSocketAddress("服务器ip",9300)));
/**
* 操作Es服务器,如果此索引存在则替换指定相同类型和id的索引和文档内容
* 第一个参数:索引名称
* 第二个参数:类型
* 第三个参数:文档id,在整个索引的相同类型中是唯一的,id存在就修改,id不存在就创建
* XContentType.JSON : 指定文档内容为json字符串格式
*/
client.prepareIndex("javaandxuan","fodd","2").
setSource("{\"id\":2,\"name\":\"轩轩喜欢敲代码\"}",XContentType.JSON).get();
client.close();
}
}
运行过后,可以看到javaand选的索引中,有数据
因为在代码中写JSON字符串,要用到转义字符,写起来比较麻烦,也可以使用fastjson,把代码中的实例对象转化为JSON字符串。也可以减少我们手写JSON字符串格式不对引起的报错。
String offerString = JSON.toJSONString(实例对象);//使用 fastjson 进行转换字符串,需要依赖jar包
client.prepareIndex("xuanandjava","offer",offer.getId()+"").
setSource(offerString, XContentType.JSON).get();
运行后可以看到指定的索引中,一样有数据
基于Transport代码实现修改(prepareUpdate)
public class Transport2_Main {
public static void main(String[] args) {
//1、创建设置对象
Settings settings=Settings.builder().put("集群key","集群名称").build();
//创建来创建对象
Client client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(new InetSocketAddress("服务器ip",9300)));
Offer offer = new Offer();
offer.setAddress("轩轩");
offer.setMoney(2500);
offer.setName("轩轩非常喜欢敲代码");
offer.setId(10);
String offerString = JSON.toJSONString(offer);//使用 fastjson 进行转换字符串,需要依赖jar包
//修改的时候,若指定的索引,类型或者id不对,则报错 DocumentMissingException
UpdateResponse updateResponse = client.prepareUpdate("xuanandjava", "offer", offer.getId() + "").
setDoc(offerString, XContentType.JSON).get();
System.out.println("听说成功:"+updateResponse.status().name());//拿到是否修改成功
client.close();
}
}
基于Transport代码实现简单查询(prepareGet)
public class Transport2_Main {
public static void main(String[] args) {
//1、创建设置对象
Settings settings=Settings.builder().put("cluster.name","qfjava").build();
//创建来创建对象
Client client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(new InetSocketAddress("服务器ip",9300)));
Offer offer = new Offer();
offer.setAddress("轩轩");
offer.setMoney(2500);
offer.setName("轩轩非常喜欢敲代码");
offer.setId(10);
//查询
GetResponse documentFields = client.prepareGet("xuanandjava", "offer", offer.getId() + "").get();
String sourceAsString = documentFields.getSourceAsString();//拿到返回的字符串(JSON)
//把字符串转为实例,因为我们拿到的字符串是JSON格式的,所以使用fastjson来转换为实例对象。
Offer offerPojo = JSON.parseObject(sourceAsString, Offer.class);
System.out.println("拿到的对象是:"+offerPojo);
client.close();
}
}
下面可以看到打印出来的实例,和ES服务器中,查询的一样。(xuanandjava索引;offer类型;id为1文本)
基于Transport代码实现删除(prepareDelete)
public class Transport2_Main {
public static void main(String[] args) {
//1、创建设置对象
Settings settings=Settings.builder().put("cluster.name","qfjava").build();
//创建来创建对象
Client client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(new InetSocketAddress("服务器ip",9300)));
Offer offer = new Offer();
offer.setAddress("轩轩");
offer.setMoney(2500);
offer.setName("轩轩非常喜欢敲代码");
offer.setId(10);
//删除指定索引;指定类型;指定id 的文档
DeleteResponse deleteResponse = client.prepareDelete("xuanandjava", "offer", offer.getId() + "").get();
String name = deleteResponse.status().name();//拿到删除的状态
System.out.println("删除结果为:"+name);
client.close();
}
}
下面可以看到,拿到的状态是:OK
Elasticsearch条件查询
Transport提供了常用的查询
批处理
- RangeQueryBuilder 范围查找 gt:大于 lt:小于 gte:大于等于 lte:小于等于
- WildcardQueryBuilder 模糊查询 使用*表示任意字符
- TermQueryBuilder 精确查询
BoolQueryBuilder 布尔类型查询 用于多条件的拼接(可用使用以下三个方法进行拼接条件)
- must 必须的 文档必须满足匹配条件
- must_not 文档必须不匹配条件
- should 或者 文档只要满足一个或多个条件
代码示例
说明:查询索引为 es1902 文档id 大于1 小于 10 类型为 offer 的文档内容,
结果以 id 为 倒序(SortOrder.DESC)
public class Transport3_Main {
public static void main(String[] args) {
//创建设置对象
Settings settings=Settings.builder().put("cluster.name","qfjava").build();
//创建来创建对象
Client client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(new InetSocketAddress("服务器ip",9300)));
/**
* 操作ES服务器(条件查询),创建查询内容
* gt:大于
* gtE:大于等于
* lt:小于
* lte:小于等于
* 这个例子的意思为 查询文档id 大于1 小于10的文档内容
*/
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("id").gt("1").lt("10");
/**
* 创建条件拼接器,一个条件的时候可用不用这个,多个条件需要使用拼接器
*/
BoolQueryBuilder booleanQueryBuilder = QueryBuilders.boolQuery();
booleanQueryBuilder.must(rangeQueryBuilder);
//创建查询对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(booleanQueryBuilder);
//执行条件查询 链式编程
SearchResponse searchResponse = client.prepareSearch("es1902").//指定查询的索引名称
setTypes("offer").//设置查询的类型,如果不写的画,就是查询全部
addSort("id",SortOrder.DESC).//设置排序,以id为倒序
setQuery(searchSourceBuilder.query()).//设置查询条件
get();//执行获取查询结果
//解析查询结果
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHit = hits.getHits();
//遍历数组
for ( SearchHit s : searchHit ){
System.out.println(s.getSourceAsString());
}
client.close();
}
Elasticsearch模糊查询
注:ElasticSearch不支持中,如果想要支持中文,需要依赖 **IK分词 **插件,这个插件主要用来语义分析
public class Transport3_Main_MoHuQuery {
public static void main(String[] args) {
//创建设置对象
Settings settings=Settings.builder().put("cluster.name","qfjava").build();
//创建来创建对象
Client client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(new InetSocketAddress("服务器ip",9300)));
/**
* 模糊查询,查询文档内容包含2的
*/
WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("name", "*2*");
//单词查询 精确查询
//TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("id","101");
/**
* 创建条件拼接器,一个条件的时候可用不用这个,多个条件需要使用拼接器
*/
BoolQueryBuilder booleanQueryBuilder = QueryBuilders.boolQuery();
booleanQueryBuilder.must(wildcardQueryBuilder);
//创建查询对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(booleanQueryBuilder);
//执行条件查询 链式编程
SearchResponse searchResponse = client.prepareSearch("es1902").//指定查询的索引名称
setTypes("offer").//设置查询的类型,如果不写的画,就是查询全部
addSort("id",SortOrder.DESC).//设置排序,以id为倒序
setQuery(searchSourceBuilder.query()).//设置查询条件
get();//执行获取查询结果
//解析查询结果
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHit = hits.getHits();
//遍历数组
for ( SearchHit s : searchHit ){
System.out.println(s.getSourceAsString());
}
client.close();
}
}
ElasticeSearch批量处理
使用 BulkRequestBuilder 来实现批量处理,这个相比循环get(),减少了于ElasticeSearch的交互次数,提高了性能
public class Transport3_Main_PIChuLi {
public static void main(String[] args) {
//创建设置对象
Settings settings=Settings.builder().put("cluster.name","qfjava").build();
//创建来创建对象
Client client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(new InetSocketAddress("服务器ip",9300)));
/**
* 操作ES服务器
* 实现批处理
*/
BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
int xuan = 1;
for (int i = 1 ; i<10001 ; i++){
Offer offer = new Offer();
offer.setAddress("上海");
offer.setMoney(15000);
offer.setName("轩轩");
offer.setId(10);
String s = JSON.toJSONString(offer);
bulkRequestBuilder.add(client.prepareIndex("xuanandjava", "offer", xuan++ + "").
setSource(s, XContentType.JSON));
}
//执行操作
BulkResponse bulkItemResponses = bulkRequestBuilder.get();
String name = bulkItemResponses.status().name();
System.out.println("批处理结果为:"+name);
client.close();
}
}