ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Es(ElasticSearch)-理解及使用(二)

2022-08-31 23:30:10  阅读:220  来源: 互联网

标签:文档 GET doc cat 索引 理解 ElasticSearch new Es


一、ElasticSearch核心概念

概述

  1. 索引(数据库)
  2. 字段类型(表)
  3. 文档(数据)
  4. 分片(Lucene索引,倒排索引)

前期可以理解为数据库

数据库-r-es

DB ElasticSearch
数据库 索引
类型(弃用)
文档
字段 fields

elasticsearch中可以包含多个索引,索引中可以包含多个类型,类型中包含多个文档

多个文档中又包含多个字段

二、ik分词器

中文分词器

把一段文字划分为一个个关键字

默认的分词是将一个个字看成一个词

ik提供了两种分词算法:

  • ik_smart:最少切分

  • ik_max_word:最细粒度划分

三、Rest风格说明

一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁更有层次更易于实现缓存等机制。

1、基本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/索引名称/类型名称/文档id/_search 查询所有数据

四、es基本操作

1、测试-创建/添加

默认文档类型_doc

(1)创建文档

PUT /t_es/_doc/1
{
  "name": "詹三",
  "age": 21,
  "introduction": "活泼、开朗、啷个帅"
}

(2)文档字段类型

  • 字符串类型
    • text :支持分词,全文检索,支持模糊、精确查询,不支持聚合,排序操作;text类型的最大支持的字符长度无限制,适合大字段存储;
    • keyword:不能进行分词,直接索引、支持模糊、支持精确匹配,支持聚合、排序操作。keyword类型的最大支持的长度为——32766个UTF-8类型的字符,可以通过设置ignore_above指定自持字符长度,超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果。
  • 数值类型
    • byte、short、integer、long、float、dubbo、half floatscaled float
  • 布尔类型
  • 二进制类型
    • binary
  • ..等..

(3)创建索引时指定字段类型

PUT /t_es_01
{
  "mappings": {
    "properties": {
       "name":{
          "type": "text"
       },
       "age":{
         "type": "long"
       },
       "introduction":{
         "type": "keyword"
       }
    }
  }
}

获取建立的规则

GET t_es_01

{
"t_es_01" : {
 "aliases" : { },
 "mappings" : {
   "dynamic_templates" : [
     {
       "message_full" : {
         "match" : "message_full",
         "mapping" : {
           "fields" : {
             "keyword" : {
               "ignore_above" : 2048,
               "type" : "keyword"
             }
           },
           "type" : "text"
         }
       }
     },
     {
       "message" : {
         "match" : "message",
         "mapping" : {
           "type" : "text"
         }
       }
     },
     {
       "strings" : {
         "match_mapping_type" : "string",
         "mapping" : {
           "type" : "keyword"
         }
       }
     }
   ],
   "properties" : {
     "age" : {
       "type" : "long"
     },
     "introduction" : {
       "type" : "keyword"
     },
     "name" : {
       "type" : "text"
     }
   }
 },
 "settings" : {
   "index" : {
     "routing" : {
       "allocation" : {
         "include" : {
           "_tier_preference" : "data_content"
         }
       }
     },
     "refresh_interval" : "30s",
     "number_of_shards" : "1",
     "translog" : {
       "sync_interval" : "5s",
       "durability" : "async"
     },
     "provided_name" : "t_es_01",
     "max_result_window" : "65536",
     "creation_date" : "1656427922030",
     "unassigned" : {
       "node_left" : {
         "delayed_timeout" : "5m"
       }
     },
     "number_of_replicas" : "1",
     "uuid" : "vsG_Di6vSPKCXzLUcJSWtg",
     "version" : {
       "created" : "7100199"
     }
   }
 }
}
}

PS: 如果自己未指定字段的类型,elasticsearch会自动配置字段类型

(4)GET _cat/的使用

GET _cat/indices

  1. GET _cat/aliases
  1. GET _cat/allocation
  1. GET _cat/count
  1. GET _cat/fielddata
  1. GET _cat/health
  1. GET _cat/indices
  1. GET _cat/master
  1. GET _cat/nodeattrs
  1. GET _cat/nodes
  1. GET _cat/pending_tasks
  1. GET _cat/plugins
  1. GET _cat/recovery
  1. GET _cat/repositories
  1. GET _cat/segments
  1. GET _cat/shards
  1. GET _cat/snapshots
  1. GET _cat/tasks
  1. GET _cat/templates
  1. GET _cat/thread_pool

参考博客:https://blog.csdn.net/iris_csdn/article/details/115860853

2、修改

两种方案

①旧的(使用put覆盖原来的值)

  • 修改后版本+1(version)

  • 缺点:如果原文档中某个字段没有写,那更新时没有书写的字段会消失

    创建

    PUT /t_es/_doc/1
    {
    "name": "詹三",
    "age": 21,
    "introduction": "活泼、开朗、啷个帅"
    }
    

    查看 GET /t_es/_doc/1

    修改

    PUT /t_es/_doc/1
    {
    "name": "詹三",
    "age": 21
    }
    

    再次查看 GET /t_es/_doc/1

②新的(使用post的update)【推荐使用】POST /索引名/_doc/文档id/_update

  • 版本不变(version)

  • 注意doc

  • 更新哪个字段就修改哪一个,其他字段不会丢失

    POST /t_es/_doc/1/_update
    {
      "doc":{
          "name": "张三丰",
          "age": 21
      }
    }
    

3、删除

DELETE /t_es

4、查询

(1)简单查询

GET /索引名/__doc/_search?q=字段名:字段值

GET /t_es/_doc/_search?q=name:张

(2)复杂查询

测试数据准备

查询所有测试数据GET /t_es/_doc/_search

①查询匹配

GET /t_es/_doc/_search{查询条件}

  • match:匹配(会使用分词器解析(先分析文档,然后进行查询))

  • term:不分割词,直接匹配倒排索引。

  • match_phrase: 将词分割开来,匹配倒排索引,查找这个短语。

  • _source:过滤字段

    • includes:需要返回的字段

    • excludes:不需要返回的字段

      {
          "_source": {
              "includes": [ "obj1.*", "obj2.*" ],
              "excludes": [ "*.description" ]
          }
      }
      
  • sort:排序

  • formsize 分页

GET /user/_doc/_search
{
  "query":{
     "match":{
       "name": "张三"
     }
  },
  "_source":{
     "includes": ["name","age"],
     "excludes": ["des"]
  },
  "sort": [
      {
        "age": {
          "order": "asc"
        }
      }
    ]
  "from":0,
  "size":1
}
②多条件查询(bool)
  • must 相当于 and

    GET /user/_doc/_search
    {
      "query":
      {
        "bool":
        {
             "must":[
               {
                 "match":{
                   "name": "张三" 
                 }
               },
               {
                 "match":{
                   "age": 4 
                 }
               }
              ]
      	 }
      	}
    }
    

  • should 相当于 or

    如果同级使用了must或者filter查询那么should的查询语句就不是或者的意思了,而是有没有都行的含义,就相当于失效了

    GET /user/_doc/_search
    {
      "query":{
        "bool":{
         "should":[
           {
             "match":{
                "age":3
             }
           },
           {
             "match":{
                "name":"张三丰"
              }  
           }
         ]
      }
      }
    }
    

  • must_not 相当于 not (... and ...)

    GET /user/_doc/_search
    {
      "query":
      {
        "bool":
        {
         "must_not":
          [
           {
             "match":
             {
                "age":5
             }
           },
           {
             "match":
              {
                "name":"张三丰"
              }  
           }
         ]
      }
      }
    }
    
  • filter 过滤

GET /user/_doc/_search
{
  "query":
  {
    "bool":
    {
      "filter":{
         "range":{
            "age":{
                "gte": 3,
                "lte": 33
            }
         }
      }
    }
  }
}
③匹配数组

④精确查询

  • term 直接通过 倒排索引 指定词条查询
  • 适合查询 number、date、keyword ,不适合text
⑤text和keyword
  • text:
    • 支持分词全文检索、支持模糊、精确查询,不支持聚合,排序操作;
    • text类型的最大支持的字符长度无限制,适合大字段存储;
  • keyword:
    • 不进行分词直接索引、支持模糊、支持精确匹配,支持聚合、排序操作。
    • keyword类型的最大支持的长度为——32766个UTF-8类型的字符,可以通过设置ignore_above指定自持字符长度,超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果
⑥高亮查询
GET /batch/_doc/_search
{
  "query":{
    "match":{
       "name": "zs1"
    }
  },
  "highlight":{
     "pre_tags": "<p style='color:red'>",
     "post_tags":"</p>",
     "fields":{
        "name":{}
     }
  }
}

五、SpringBoot中使用

1、导入依赖

 <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.10.1</elasticsearch.version>
    </properties>
    <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>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.53</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2、配置文件

spring:
  elasticsearch:
    uris: https://localhost:9200
    username: 
    password: 

3、交给spring容器管理

RestHighLevelClient

@Configurable
public class EsConfig {
    @Value("${spring.elasticsearch.username}")
    public String username;
    @Value("${spring.elasticsearch.password}")
    public String password;

    @Bean(destroyMethod = "close")
    public RestHighLevelClient restHighLevelClient(){
        // 设置验证信息,填写账号及密码
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
        // 初始化 RestClient, hostName 和 port 填写集群的内网 VIP 地址与端口
        RestClientBuilder builder = RestClient.builder(new HttpHost("es-duhh30zz.public.tencentelasticsearch.com", 9200, "https"));
        // 设置认证信息
        builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
            @Override
            public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
            }
        });
        // 由Low Level Client构造High Level Client
        return new RestHighLevelClient(builder);
    }
}

4、测试

索引操作

(1)创建索引

    @Test
    void contextLoads() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("test");
         //boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);//判断索引是否存在
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(response.isAcknowledged());
    }

(2)删除索引

   import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
   @Test
    void contextLoads() throws IOException {
        DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("test");
        AcknowledgedResponse delete = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
        System.out.println(delete);
        System.out.println("is Delete:"+delete.isAcknowledged());
    }

文档操作

(1)添加文档

/**
     * 创建索引并将user对象中的数据存储在es中
     */
    @Test
    public void testIndex() throws IOException {
        String index =  "user_index";
        //1、判断索引是否创建
        GetIndexRequest getIndexRequest = new GetIndexRequest(index);
        boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        if(!exists){//不存在
            CreateIndexRequest indexRequest = new CreateIndexRequest("user_index");
            client.indices().create(indexRequest, RequestOptions.DEFAULT);
        }
        //2、向索引中添加文档
        IndexRequest indexRequest = new IndexRequest(index);
        //2.1 设置文档id
        indexRequest.id("1");
        indexRequest.timeout(TimeValue.timeValueMillis(3000));//超时时间 3s
        //2.2 设置文档内容
        User user = new User("张三",18L);
        indexRequest.source(JSON.toJSONString(user), XContentType.JSON);
        //3、客户端发送请求,查看存放信息
        IndexResponse index1 = client.index(indexRequest, RequestOptions.DEFAULT);
        //获取创建的状态以及返回结果
        System.out.println("status:" + index1.status());
        System.out.println(index1);
    }
  • 批量添加文档

    @Test
        public void testbatch() throws IOException {
            BulkRequest bulkRequest = new BulkRequest();
            bulkRequest.timeout(TimeValue.timeValueMillis(10000));//10s
            List<User> list = new ArrayList<>();
            list.add(new User("zs1",1L));
            list.add(new User("zs2",2L));
            list.add(new User("zs3",3L));
            list.add(new User("zs4",4L));
            list.add(new User("zs5",5L));
            list.add(new User("zs6",6L));
            int len = list.size();
            //批量请求处理
            for(int i=0;i<len;i++){
                bulkRequest.add(
                        new IndexRequest("batch")
                                .id(""+(i+1))//若不设置id会随机生成
                                .source(JSON.toJSONString(list.get(i)),XContentType.JSON)
                );
            }
            BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
            System.out.println(bulk.status());//转态
            System.out.println(bulk.hasFailures());//是否失败
        }
    

(2)查询文档

  • 简单查询
 @Test
    public void getIndex() throws IOException {
        GetRequest request = new GetRequest("user_index","1");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        System.out.println("index:"+response.getIndex());
        System.out.println("content:"+response.getSourceAsString());
        System.out.println("all:"+request);
    }
  • 复杂查询

基本的

@Test
 public void testSelect() throws IOException {
     //1、创建查询对象
     SearchRequest searchRequest = new SearchRequest();

     //2、构建搜索条件
     SearchSourceBuilder builder = new SearchSourceBuilder();
     //(1)查询条件使用QueryBuilders
     TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "zs1");//精确查找
//        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();//查询所有
//分页
     builder.from(0);
     builder.size(3);
     //(2)高亮显示
//    builder.highlighter(new HighlightBuilder());
     //超时
     builder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//        (3)、查询条件投入
     builder.query(termQueryBuilder);

     //3、添加查询条件到请求
     searchRequest.source(builder);
     //4、客户端请求
     SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
     System.out.println(search);
     //5、请求结果
     SearchHits hits = search.getHits();
     System.out.println(JSON.toJSONString(hits));
     System.out.println("-----------------");
     for (SearchHit documentFields : hits.getHits()) {
         System.out.println(documentFields.getSourceAsMap());
     }
 }

(3)根据文档id查询、判断查询的文档是否存在

@Test
    public void getIndexExit() throws IOException {
        GetRequest request = new GetRequest("user_index","1");
        //不获取返回_source的上下文效率更高
        request.fetchSourceContext(new FetchSourceContext(false));
        request.storedFields("_none_");
        boolean exists = client.exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

(4)更新文档

@Test
    public void testUpdateDocument() throws IOException {
        UpdateRequest request = new UpdateRequest("user_index","1");
        User user = new User("斩杀",22L);
        request.doc(JSON.toJSON(user),XContentType.JSON);
        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
        System.out.println("status:"+update.status());
        System.out.println(request);
    }

(5) 删除文档

  @Test
    public void delDocument() throws IOException {
        DeleteRequest request = new DeleteRequest("user_index","1");
        DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(delete);
        System.out.println("status:"+delete.status());
    }

参考:https://www.kuangstudy.com/bbs/1354069127022583809

标签:文档,GET,doc,cat,索引,理解,ElasticSearch,new,Es
来源: https://www.cnblogs.com/zceng/p/16644939.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有