ES (ElasticSearch) 的基本入门(一)

本文详细介绍了Elasticsearch的基本概念、应用场景及痛点,强调了其在大数据搜索和日志分析中的作用。文章还深入讲解了倒排索引和存储方式,并提供了Linux环境下ES的安装步骤,包括配置文件修改和内存调整。同时,文章讨论了IK分词器的安装和使用,展示了如何在SpringBoot中操作ES。通过实例展示了索引、文档的增删改查操作,以及分词器在全文搜索中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. Es的概念

  1. es是基于lucene的搜索服务器
  2. 是一个分布式、高扩展、高实时的搜索数据分析引擎
  3. 基于restful接口
  4. 开源!基于java 开发的

应用场景主要是 海量数据的搜索、日志数据的分析、实时数据的分析。

1. ES的痛点

ES 是一个搜索服务器,那么为什么会有这个搜索服务的器功能呢?那肯定是因为我们的sql 查询满足不了一些相关的搜索。

  1. 在数据量特别大的时候,用Like ‘%xx’ 这样的语句会让索引失效,进而会非常慢!
  2. 我们百度的时候,可以观察一下,搜苹果手机,前面肯定都是匹配的苹果手机四个字,但是越往后就是,苹果和手机了。我要实现这样的功能,关系型数据库的搜索是无法满足的。

1.2 Es的倒排索引

有倒排就有正排索引。

我们在学生时代的时候语文有一个题形,简单的就是比如 故人西辞黄鹤楼 下一句是什么。难的怎么考,比如落霞与孤鹜齐飞上一句是什么?有的小伙伴就蒙圈了。我们背书的时候,习惯就是从上一句背到下一句,某种意义上,上一句就是下一句的索引,很快啊!就可以在大脑了里查出来,但是后一句问上一句,就不行了,猪脑直接过载,为什么因为我们没有创建这个倒排索引。

当然这边只是让大家理解这个意思,真正体现到数据库的就是我关键字当索引。

1.3 Es 存储方式

对于关系型数据库里的数据,es 这边称之为一个document ,每个document的某个字段会通过分词器分完之后和document存储一个关联关系,当然一个词会和多个document关联上关系。我们查询某个词汇的时候也会将这个词汇先进行分词,然后通过这个分词去查找对应的document。

2. es的安装

开始实操!下载地址

我这边选用的是linux 版本安装,我的版本是elasticsearch-7.4.0,注意我这边的配置只针对这个版本。es 是用java 语言编写的,下面我改了一下es 的配置文件elasticsearch.yml

cluster.name: my-application  #名称
node.name: node-zx  #节点名称
network.host: 0.0.0.0 #是否能远程访问 
http.port: 9200  #端口
cluster.initial_master_nodes: ["node-zx"] #主节点

我的虚拟机是1g的内存不够,就改了运行内存大小,从1g -> 512m,如果内存不够就会直接闪退。也不会报错。 

这边的注意点就是不能用root用户启动,得申请一个用户,然后把es赋权给这个用户,最后启动一下就行。

2.1 kibana 官方插件工具

下载地址 我这边的版本还是7.4.0

解压命令

tar -zxvf kibana-7.4.0-linux-x86_64.tar.gz 

修改配置,都是常规配置。

server.port: 5601
server.host: "0.0.0.0"
server.name: "kib"
elasticsearch.hosts: ["http://127.0.0.1:9200"]
elasticsearch.requestTimeout: 99999

3.操作索引

因为是restful风格,这边用postman 操作就行 

 4 kibana 操作映射

 5.操作文档

增删改查所有操作。

6 分词器

标准分词器效果演示,这种对于中文来说非常不友好,这个对于英文来说还行。

 6.1 IK分词器

首先下载安装maven 下载地址,这一步不是很重要。

再次下载IK分词器的安装包 下载地址

下完了之后在/www/wwwroot/elasticsearch-7.4.0/plugins 

在这个目录创建一个自己的文件夹,把压缩IK的分词器的包放入这个文件夹解压。

然后把这个解压出来的config文件放入es的config文件夹下,重启es 就大功告成了

下面就是用IK分词器的两种写法

6.1.1 ik 查询

# 普通查询就是一个字一个字德查询term 查询
#这个查询就是按照词条去查询
GET yxlm/_search
{
  "query":{
    "term": {
      "country": {
        "value": "北京靖江"
      }
    }
  }  
}
#这边的查询就是会将你的查询条件进行分词之后再去查询
#这样就可以查询
GET yxlm/_search
{
  "query":{
    "match": {
      "country": "南京靖江"
    }
  }  
}
#创建索引的时候记住用ik 自带的分词器
PUT /yxlm
{
  "mappings":{
    "properties":{
    "name":{
      "type":"text"
    },
    "age":{
      "type":"integer"
    },
    "country":{
      "type":"text",
      "analyzer":"ik_max_word"
    }
  }
  }
}

#然后给索引添加数据,其实就是将这个数据和索引进行一个关联关系的绑定
POST yxlm/_doc
{
  "name":"beij" ,
  "country":"我家住在靖江",
  "age":12
}


DELETE yxlm

以上就是ik分词器结合es的使用。

7. springboot 操作es

7.0 首先是pom文件

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <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>
    </dependencies>

7.1 配置类

注意这边的参数是配置在配置文件里面的

package com.example.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class EsConfig {
    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 getEsClient(){
         RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(
                 new HttpHost(host,port,"http")
         ));
         return restHighLevelClient;
     }
}

7.2 操作索引

这边就是索引的增删改查询操作

package com.example;

import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsApplication.class)
public class EsApplicationTest {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Test
    public void esTest(){
//        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(
//              new HttpHost("124.223.99.145",9200,"http")
//        ));

        System.out.println(restHighLevelClient);
    }
    //这个仅仅就是添加索引,还没有添加索引的相关检索字段
    @Test
    public void addIndex() throws IOException {
        //操作索引
        IndicesClient indices = restHighLevelClient.indices();
        //创建索引
        CreateIndexRequest index = new CreateIndexRequest("china");
        //创建返回值
        CreateIndexResponse createIndexResponse = indices.create(index, RequestOptions.DEFAULT);
        boolean acknowledged = createIndexResponse.isAcknowledged();
        System.out.println(acknowledged);
    }

    /**
     * 添加索引以及对应的属性,这边的属性就是,对象分词的一些东西
     * @throws IOException
     */
    @Test
    public void addIndexAndMapping() throws IOException {
        //操作索引
        IndicesClient indices = restHighLevelClient.indices();
        //创建索引,注意这边的对象有两个差不多的,用新款对象,老款对象的方法已经废弃了,注意分别
        CreateIndexRequest index = new CreateIndexRequest("chinaandmapping");
        //处理索引的属性
        index.mapping("{\n" +
                "      \"properties\" : {\n" +
                "        \"age\" : {\n" +
                "          \"type\" : \"integer\"\n" +
                "        },\n" +
                "        \"country\" : {\n" +
                "          \"type\" : \"text\",\n" +
                "          \"analyzer\" : \"ik_max_word\"\n" +
                "        },\n" +
                "        \"name\" : {\n" +
                "          \"type\" : \"text\"\n" +
                "        }\n" +
                "      }\n" +
                "    }",XContentType.JSON);
        //创建返回值
        CreateIndexResponse createIndexResponse = indices.create(index, RequestOptions.DEFAULT);
        boolean acknowledged = createIndexResponse.isAcknowledged();
        System.out.println(acknowledged);
    }
    @Test
    public void queryIndex() throws IOException {
        //操作索引
        IndicesClient indices = restHighLevelClient.indices();
        GetIndexRequest index = new GetIndexRequest("chinaandmapping");
        GetIndexResponse getIndexResponse = indices.get(index, RequestOptions.DEFAULT);
        Map<String, MappingMetaData> mappings = getIndexResponse.getMappings();
        for(String key : mappings.keySet()){
            System.out.println(key+ mappings.get(key).getSourceAsMap());
        }
    }


    @Test
    public void deleteIndex() throws IOException {
        //操作索引
        IndicesClient indices = restHighLevelClient.indices();
        DeleteIndexRequest index = new DeleteIndexRequest("chinaandmapping");
        AcknowledgedResponse delete = indices.delete(index, RequestOptions.DEFAULT);
        System.out.println(delete.isAcknowledged());
    }

    @Test
    public void getIndex() throws IOException {
        //操作索引
        IndicesClient indices = restHighLevelClient.indices();
        GetIndexRequest request = new GetIndexRequest("chinaandmapping");
        boolean exists = indices.exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }
}

7.3 操作文档

/**
     * 添加文档 对象
     * @throws IOException
     */
    @Test
    public void addDocByObj() throws IOException {
        YxlmObj yxlm = new YxlmObj();
        yxlm.setAge(2);
        yxlm.setCountry("我家住在山西县");
        yxlm.setName("李云龙222");
        yxlm.setId("2");
        IndexRequest yxlmindex = new IndexRequest("yxlm").id(yxlm.getId()).source(JSON.toJSONString(yxlm),XContentType.JSON);
        IndexResponse index = restHighLevelClient.index(yxlmindex, RequestOptions.DEFAULT);
        System.out.println(index.getId());
    }
    @Test
    public void updateDocByObj() throws IOException {
       //修改就是上面的增加,如果id是一样的就会是修改操作
    }

    /**
     * 查询操作
     * @throws IOException
     */
    @Test
    public void findDocByObj() throws IOException {
        GetRequest getRequest = new GetRequest("yxlm","1");
        GetResponse documentFields = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        String sourceAsString = documentFields.getSourceAsString();
        System.out.println(sourceAsString);
    }

    @Test
    public void deleteDocByObj() throws IOException {
        DeleteRequest deleteRequest = new DeleteRequest("yxlm","1");
        DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        String id = delete.getId();
        System.out.println(id);

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值