搜索! 以后只需要用到搜索,就可以使用ES!(大数据量的情况下使用!)
1.ElasticSearch概述
Elaticsearch,简称为es(以下我们使用简称) ,es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别(大数据时代)的数据。es也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTfulAPI来隐藏Lucene的复杂性,从而让全文搜索变得简单。
据国际权威的数据库产品评测机构DBEngines的统计,在2016年1月,ElasticSearch已超过Solr等,成为排名第一的搜索引擎类应用。
2.ES与solr的区别
ES:是一个实时分布式搜索和分析引擎。它让你以前所未有的速度处理大数据成为可能。 它用于全文搜索、结构化搜索、分析以及将这三者混合使用
Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
但是,Lucene只是一个库。想要使用它,你必须使用lava来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。
Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的 RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
Solr:是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。
总结:
1、ES基本是开箱即用(解压就可以用!),非常简单。Solr安装略微复杂一丢丢!
2、Solr 利用Zookeeper进行分布式管理,而Elasticsearch自身带有分布式协调管理功能。
3、Solr 支持更多格式的数据,比如JSON、XML、CSV,而Elasticsearch仅支持json文件格式。
4、Solr官方提供的功能更多,而Elasticsearch本身更注重于核心功能,高级功能多有第三方插件提供,例如图形化界面需要Kibana友好支撑
5、Solr查询快,但更新索引时慢(即插入删除慢),用于电商等查询多的应用﹔
-
ES建立索引快(即查询慢),即实时性查询快,用于facebook新浪等搜索。
-
Solr是传统搜索应用的有力解决方案,但Elasticsearch更适用于新兴的实时搜索应用。
6、Solr比较成熟,有一个更大,更成熟的用户、开发和贡献者社区,而Elasticsearch相对开发维护者较少,更新太快,学习使用成本较高。
3.安装
window 下安装
1、解压
2、熟悉目录
bin 启动文件
config 配置文件
log4j2 日志配置文件
jvm.options java 虚拟机相关的配置
elasticsearch.yml elasticsearch 的配置文件!默认 9200端口!跨域
lib 相关jar包
logs: 日志!
modules 功能模块
plugins 插件! ik分词器
3、启动,访问9200;
4、访问测试
4.Kibana
Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana ,可以通过各种图表进行高级数据分析及展示。Kibana让海量数据更容易理解。它操作简单,基于浏览器的用户界面可以快速创建仪表板( dashboard )实时显示Elasticsearch查询动态。设置Kibana非常简单。无需编码或者额外的基础架构,几分钟内就可以完成Kibana安装并启动Elasticsearch索引监测。"
Kibana版主要与ES版本一致!
1.解压
2.启动
3.访问测试
我们之后的所有操作,都在这里编写!
汉化:修改配置文件即可!
5.ES核心概念
1、索引
2、字段类型(mapping)
3、文档
4、分片(倒排索引)
6.ik分词器
什么是IK分词器?
分词∶即把一段中文或者别的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词,比如“我爱狂神"会被分为"我"爱"狂""神",这显然是不符合要求的,所以我们需要安装中文分词器ik来解决这个问题。
如果要使用中文,建议使用ik分词器!
IK提供了两个分词算法:ik_smart和ik_max_word,其中ik_smart为最少切分,ik_max_word为最细粒度划分!
安装
1、下载
2、下载完毕后,放入我们的elasticsearch插件中即可
3、重启观察elasticsearch,可以看到ik分词器被加载了!
4、elasticsearch-plugin 可以通过这个命令来查看加载进来的插件!
5、使用Kibana测试!
ik_smart为最少切分
ik_max_word为最细粒度划分:会进行进一步的划分
发现问题:会移动的树被拆开了!
这种自己需要的词,需要自己加到我们的分词器字典中!
ik分词器 增加自己的配置:
重启ES,看细节
效果:
关于索引的基本操作以及关于文档(行)的基本操作,就不细说了!!
7.集成SpringBoot
1、找到原生的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
2、配置基本的项目
具体测试:
1、创建索引
// 测试索引的创建 Request
@Test
void testCreateIndex() throws IOException {
//1、创建索引请求
CreateIndexRequest request = new CreateIndexRequest("bo_index");
//2、执行创建请求
CreateIndexResponse createIndexResponse =
client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse); //org.elasticsearch.client.indices.CreateIndexResponse@5c31f8ff
}
2、判断索引是否存在
//测试获取索引,只能判断其存不存在
@Test
void testExistIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("bo_index");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists); //true
}
3、删除索引
//测试删除索引
@Test
void testDELIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("bo_index");
//删除
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged()); //true
}
4、创建文档
//测试添加文档
@Test
void testAddDocument() throws IOException {
//1、创建对象
User user = new User("小美",3);
//2、创建请求
IndexRequest request = new IndexRequest("bo_index");
// 规则 put /bo_index/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
request.timeout("1s");
//将我们的数据放入请求
request.source(JSON.toJSONString(user), XContentType.JSON);
//客户端发生请求,获取响应的结果
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
System.out.println(indexResponse.status()); // 对应我没命令的返回状态 CREATED
}
5、判断文档是否存在
//测试获取文档,判断是否存在 get /index/doc/1
@Test
void testExistDocument() throws IOException {
GetRequest getRequest = new GetRequest("bo_index", "1");
// 不获取返回的_source 的上下文了
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists); //true
}
6、crud文档
//获取文档信息
@Test
void testGetDocument() throws IOException {
GetRequest getRequest = new GetRequest("bo_index", "1");
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println(getResponse.getSourceAsString()); //打印文档的内容 {"age":3,"name":"小美"}
System.out.println(getResponse);//返回的全部内容和命令是一样的
}
//更新文档的信息
@Test
void testUpdateDocument() throws IOException {
UpdateRequest updateRequest = new UpdateRequest("bo_index", "1");
updateRequest.timeout("1s");
User user = new User("小美", 18);
updateRequest.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse update = client.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(update.status()); //OK
}
//删除文档记录
@Test
void testDeleteDocument() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("bo_index", "1");
deleteRequest.timeout("1s");
DeleteResponse delete = client.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(delete.status()); //OK
}
7、批量操作数据
//特殊的,真的项目一般都会批量插入数据!
@Test
void testBulkDocument() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("1s");
ArrayList<User> list = new ArrayList<>();
list.add(new User("小美1",5));
list.add(new User("小美2",6));
list.add(new User("小美3",7));
list.add(new User("小美4",8));
list.add(new User("小美5",9));
list.add(new User("小美6",10));
//批处理请求
for (int i = 0; i < list.size(); i++) {
//批量更新和批量删除,就在这里修改对应的请求即可
bulkRequest.add(new IndexRequest("bo_index")
.id("" + (i+1)) //没有id会生成一个随机id
.source(JSON.toJSONString(list.get(i)),XContentType.JSON));
}
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.hasFailures()); //false 是否失败,返回false,代表成功
}
8、查询
//查询
// searchRequest 搜索请求
//searchSourceBuilder 条件构造
// HighlightBuilder 构建高亮
// TermQueryBuilder 精确查询
//MatchAllQueryBuilder 匹配全部
// xxxQueryBuilder
@Test
void testSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest(ESconst.ES_INDEX);
//构建搜索的条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//查询条件,我们可以使用 QueryBuilders 工具类实现
//QueryBuilders.termQuery 精确
//QueryBuilders.matchAllQuery() 匹配所有
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "gongbo1");//精确查询
// MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
searchSourceBuilder.query(termQueryBuilder);
// searchSourceBuilder.from();
// searchSourceBuilder.size();
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(searchSourceBuilder);
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits()));
System.out.println("==========================================");
for (SearchHit hit : search.getHits().getHits()) {
System.out.println(hit.getSourceAsMap()); //{name=xiaomei1, age=3}
}
}