ElasticSearch
- Lucene是一套信息检索包,jar包,不包含搜索引擎系统
- ElasticSearch是基于Lucene做了一些封装和增强
- 数据分析ELK技术:ElasticSearch+logstash+kibana
Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。
安装ElasticSearch
ElasticSearch基本概念
-
索引(Index)
ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。 -
类型(Type)
类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。 -
文档(Document)
文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。 -
映射(Mapping)
ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等等。另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。 -
节点(Node)
运行了单个实例的ES主机称为节点,它是集群的一个成员,可以存储数据、参与集群索引及搜索操作。类似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。用户可以按需要自定义任何希望使用的名称,但出于管理的目的,此名称应该尽可能有较好的识别性。节点通过为其配置的ES集群名称确定其所要加入的集群。 -
分片(Shard)和副本(Replica)
ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。每个分片其内部都是一个全功能且独立的索引,因此可由集群中的任何主机存储。创建索引时,用户可指定其分片的数量,默认数量为5个。
IK分词器插件
- 把一段中文划分为一个个关键字
- IK分词器提供两个分词算法:
- ik_smart(最少切分):不会重复
- ik_max_word(最细粒度划分)
- 安装插件,在kibana中测试
ik分词器增加自定义配置
- 配置文件:elasticsearch-7.8.0\plugins\ik\config\IKAnalyzer.cfg.xml
- config目录下新建dic文件,添加自己的词
- 重启es,就可以匹配自己添加的词库了
Rest风格
- Rest是一种软件架构风格,而不是标准,只是提供一组设计原则和约束条件
- 关于索引的基本操作
method | url地址 | 描述 |
---|---|---|
PUT | localhost:9200/索引名称/类型名称/文档id | 创建文档(指定文档id) |
POST | localhost:9200/索引名称/类型名称/ | 创建文档(随机文档id) |
POST | localhost:9200/索引名称/类型名称/文档id/_update | 修改文档 |
DELETE | localhost:9200/索引名称/类型名称/文档id | 删除文档 |
GET | localhost:9200/索引名称/类型名称/文档id | 查询文档(通过文档id) |
POST | localhost:9200/索引名称/类型名称/_search | 查询所有数据 |
- 添加一个索引
PUT /test1/type1/1
{
"name": "huang",
"age": 18
}
GET test1 #获得索引信息
GET _cat/indices?v #_cat可以获得es当前的很多信息
文档查询
- 查处结果中有_score选项,匹配度越高,分值越高
- 查询参数体中编辑参数:
- query:match:匹配数据
- _source:结果过滤
- sort:排序
SpringBoot集成ES
- 原生依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.1</version>
</dependency>
- springboot的es版本设置为和自己的一样
<properties>
<java.version>11</java.version>
<!--自定义ES版本-->
<elasticsearch.version>7.8.0</elasticsearch.version>
</properties>
- 注入bean
@Configuration
public class ESconfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
}
}
- 测试索引操作
@SpringBootTest
class TestApplicationTests {
@Autowired
@Qualifier(value = "restHighLevelClient")
private RestHighLevelClient client;
@Test
void testCreate() throws IOException {
//创建索引请求
CreateIndexRequest request = new CreateIndexRequest("huang_index1");
//执行请求,获得相应
CreateIndexResponse response =
client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(response);
}
@Test
void testExit() throws IOException {
//获取索引
GetIndexRequest request = new GetIndexRequest("huang_index1");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
@Test
void testDel() throws IOException {
//删除索引
DeleteIndexRequest request = new DeleteIndexRequest("huang_index");
AcknowledgedResponse response =
client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(response);
}
}
//添加文档
@Test
void testAddDocument() throws IOException {
//创建对象
User user = new User("name",18);
//创建请求
IndexRequest request = new IndexRequest("huang");
request.id("1");
request.timeout(TimeValue.timeValueSeconds(5));
//将数据放入请求
request.source(JSON.toJSONString(user), XContentType.JSON);
//客户端发送请求
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println(response.toString());
}
//获取文档
@Test
void testExitDocument() throws IOException {
GetRequest request = new GetRequest("huang", "1");
boolean exists = client.exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
//获取文档信息
@Test
void testGetDoucent() throws IOException {
GetRequest request = new GetRequest("huang", "1");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
System.out.println(response.getSourceAsString());
System.out.println(response);
}
//更新文档信息
@Test
void testUpdateDocument() throws IOException {
UpdateRequest request = new UpdateRequest("huang", "1");
request.timeout("1s");
request.doc(JSON.toJSONString(new User("yao",3)),XContentType.JSON);
UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
System.out.println(update);
}
//删除文档记录
@Test
void testDelDocument() throws IOException {
DeleteRequest request = new DeleteRequest("huang", "1");
request.timeout("1s");
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println(response);
}
//批量插入数据
@Test
void testManyD() throws IOException {
BulkRequest request = new BulkRequest();
request.timeout("10s");
ArrayList<User> users = new ArrayList<>();
users.add(new User("a",1));
users.add(new User("b",1));
users.add(new User("c",1));
users.add(new User("d",1));
for (int i = 0; i < users.size(); i++) {
request.add(
new IndexRequest("huang")
.id(""+i)
.source(JSON.toJSONString(users.get(i)),XContentType.JSON)
);
}
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println(response.hasFailures());
}
//查询
@Test
void testSearch() throws IOException {
SearchRequest request = new SearchRequest("huang");
//构建搜索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//xxxxQueryBuilder构造查询条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "huang");
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
request.source(sourceBuilder);
//执行
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(response.getHits()));
}