1、概念
- ElasticSearch是一个基于Lucene的搜索服务器
- 是一个分布式、高扩展、高实时的搜索与数据分析引擎
- 基于RESTful web接口
- Elasticsearch是用Java语言开发的,底层就是Lucene
- 常用于海量信息的查询
补充知识:
Elasticsearch是ELK的一个组成,是其中的一个产品,而且是非常完善的产品,ELK代表的是:E就是ElasticSearch,L就是Logstach(数据采集和同步,操作日志),K就是kibana(数据可视化分析)
2、ElasticSearch核心概念
索引(index)
ElasticSearch存储数据的地方,可以理解成关系型数据库中的数据库概念。
映射(mapping)
mapping定义了每个字段的类型、字段所使用的分词器等。相当于关系型数据库中的表结构。
文档(document)
Elasticsearch中的最小数据单元,常以json格式显示。一个document相当于关系型数据库中的一行数据。
倒排索引
一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,对应一个包含它的文档id列表。
倒排索引是es的核心,我们正常操作数据库是根据ID查内容,倒排索引是根据内容查ID,然后再拿着ID去查询出来真正需要的东西。
类型(type)
一种type就像一类表。如用户表、角色表等。在Elasticsearch7.* 默认type为_doc。
总结上述内容将Elasticsearch和关系型数据术语对照:
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引(Index) ⇒ 类型(type) ⇒ 文档(Docments) ⇒ 字段(Fields)
3、es的索引和mysql索引的区别
说到ES的索引,那么我们不免会想到MySQL的索引,那么他们之间到底有啥区别呢,相信大家也都知道这是面试官们非常喜欢问的问题。
数据库索引是一种单独的、物理的 对数据库表中一列或多列的值进行排序的一种存储结构,你可以认为它类似于一本书的目录,你可以通过目录轻易的找到你所要的内容。
要知道MySQL5.5之后的版本索引都使用的是B+Tree,但是为什么使用B+Tree呢他尽力了漫长的优化想要详细了解请看 曾经,我以为我很懂MySQL索引 这里我只放一张图,大家懂得都懂,不懂就看上面的连接更深入的学习一哈!
ES 索引,在ES中使用的其实是倒排索引,那么什么又是倒排索引呢?为了方便理解我们先介绍正排索引
正排索引就是文档(Document)和它的字段Fields正向对应的关系:也就是用id查内容
id | book | content |
1 | 静夜思 | 床前明月光,疑是地上霜 |
2 | 水调歌头 | 明月几时有?把酒问青天 |
3 | 望月怀远 | 海上生明月,天涯共此时 |
倒排索引就是用内容查找对应的id
content | id |
明月 | 【1,2,3】 |
床前 | 【1】 |
海上 | 【3】 |
倒排索引搞清楚了,但是怎么能高效的查询呢?
这里我们引用到两个新的概念:Term Dictionary,Term Index
我们将一个文本拆分成一个一个独立Term 其实就是我们常说的分词。而将所有 Term 合并在一起就是一个 Term Dictionary,也可以叫做单词词典。但是分词多了也就不高效了,所以有引入了Term Index,我们为Term Dictionary 创建一个索引然后放入内存中,这样就减少了io次数,提高了查询效率。
4、RESTful风格操作
操作索引
#添加
PUT http://ip:端口/索引名称
#查询
GET http://ip:端口/索引名称 # 查询单个索引信息
GET http://ip:端口/索引名称1,索引名称2... # 查询多个索引信息
GET http://ip:端口/_all # 查询所有索引信息
#删除
DELETE http://ip:端口/索引名称
#关闭、打开索引
POST http://ip:端口/索引名称/_close
POST http://ip:端口/索引名称/_open
操作映射
#创建索引并添加映射
PUT /person
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
}
}
}
}
#查询映射
GET person/_mapping
#添加字段
PUT /person/_mapping
{
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
}
}
}
操作文档
添加文档,指定id
POST /person/_doc/1
{
"name":"张三",
"age":18,
"address":"北京"
}
#查询所有文档
GET /person/_doc/1
#查询所有文档
GET /person/_search
#添加文档,不指定id
POST /person1/_doc/
{
"name":"张三",
"age":18,
"address":"北京"
}
#删除指定id文档
DELETE /person/_doc/1
5、分词器
IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。
IK提供两种分词模式:智能模式和细粒度模式
{ 智能(组粒度):对应es的IK插件的ik_smart,细粒度:对应es的IK插件的ik_max_word }
6、SpringBoot整合ES
①搭建SpringBoot工程
②引入ElasticSearch相关坐标
<!--引入es的坐标-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.4.0</version>
</dependency>
application.yml
elasticsearch:
host: 192.168.200.128
port: 9200
③测试
ElasticSearchConfig
@Configuration
@ConfigurationProperties(prefix="elasticsearch")
public class ElasticSearchConfig {
private String host;
private int port;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Bean
public RestHighLevelClient client(){
return new RestHighLevelClient(RestClient.builder(
new HttpHost(host,port,"http")
));
}
}
@SpringBootTest
class ElasticsearchDay01ApplicationTests {
@Autowired
RestHighLevelClient client;
/**
* 测试
*/
@Test
void contextLoads() {
System.out.println(client);
}
}
1.添加索引
/**
* 添加索引
* @throws IOException
*/
@Test
public void addIndex() throws IOException {
//1.使用client获取操作索引对象
IndicesClient indices = client.indices();
//2.具体操作获取返回值
//2.1 设置索引名称
CreateIndexRequest createIndexRequest=new CreateIndexRequest("itheima");
CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
//3.根据返回值判断结果
System.out.println(createIndexResponse.isAcknowledged());
}
2.添加索引,并添加映射
/**
* 添加索引,并添加映射
*/
@Test
public void addIndexAndMapping() throws IOException {
//1.使用client获取操作索引对象
IndicesClient indices = client.indices();
//2.具体操作获取返回值
//2.具体操作,获取返回值
CreateIndexRequest createIndexRequest = new CreateIndexRequest("itcast");
//2.1 设置mappings
String mapping = "{\n" +
" \"properties\" : {\n" +
" \"address\" : {\n" +
" \"type\" : \"text\",\n" +
" \"analyzer\" : \"ik_max_word\"\n" +
" },\n" +
" \"age\" : {\n" +
" \"type\" : \"long\"\n" +
" },\n" +
" \"name\" : {\n" +
" \"type\" : \"keyword\"\n" +
" }\n" +
" }\n" +
" }";
createIndexRequest.mapping(mapping,XContentType.JSON);
CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
//3.根据返回值判断结果
System.out.println(createIndexResponse.isAcknowledged());
}
3.查询索引
/**
* 查询索引
*/
@Test
public void queryIndex() throws IOException {
IndicesClient indices = client.indices();
GetIndexRequest getRequest=new GetIndexRequest("itcast");
GetIndexResponse response = indices.get(getRequest, RequestOptions.DEFAULT);
Map<String, MappingMetaData> mappings = response.getMappings();
//iter 提示foreach
for (String key : mappings.keySet()) {
System.out.println(key+"==="+mappings.get(key).getSourceAsMap());
}
}
4.删除索引
/**
* 删除索引
*/
@Test
public void deleteIndex() throws IOException {
IndicesClient indices = client.indices();
DeleteIndexRequest deleteRequest=new DeleteIndexRequest("itheima");
AcknowledgedResponse delete = indices.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}