elasticsearch基础学习笔记

161 阅读5分钟

目前市面比较常用的搜索引擎,都是基于Lucene的搜索服务器,用Java开发而成

elasticsearch提供了一个分布式多用户能力的全文搜索引擎,索引方式:json

Elasticsearch核心概念

  • 全文检索
  • 全文索引
  • 接近实时
  • 索引
  • 倒排索引
  • 类型
  • 文档
  • 分片和复制
  • 集群
  • 节点

PS:倒排索引的出现,弱化了type的概念和功能,且在elasticsearch 7.x中已经删除了type的概念,也就是没有表的概念了

安装步骤省略...

安装过程中遇到的问题

  1. mac 本机安装时启动报错

解决方案:es版本和jdk版本不匹配

  1. 启动报错:could not find java in JAVA_HOME at $(/usr/libexec/java_home -v 11)/bin/java

解决方案:www.jianshu.com/p/9b334e42a…

  1. 其他问题暂时未记录(在linux系统上还会有一个基本的问题,es处于安全考虑,要用非root用户启动,root账户启动报错,mac本机未遇到该问题)

了解说明:因为默认登录的管理员和root是有区别的,默认登录的就是普通管理员用户,所以没出现该错误

  1. 后台启动时报警告( ./elasticsearch -d):Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
    未进行影响正常启动,大致百度了下原因

解决方案:blog.csdn.net/m0_60264772…

  1. 启动成功测试

索引操作(index)

创建索引:(索引==mysql中的表)PUT,索引名称只能小写

获取索引信息:GET

查看ES中所有索引:GET,请求入参改变:_cat/indices?v 参数v相当于格式化了下,不传也可以

删除索引:DELETE

文档操作(doc)

创建文档(插入数据):POST,索引名/_doc

自定义ID:索引名/_create/id 等同于 索引名/_doc/id

区别:_create/id 如果数据重复会报错 ---幂等性,所以在指定ID的时候也可使用PUT请求(具有幂等性)

_doc/id 如果ID一样内容不一样则update

自定义ID好处:便于查询,不传则随机生成ID,当然es的出现查询也不会通过ID去查询

查看文档(数据):单条

查询该索引下所有文档:_search

根据蛋哥单个属性条件查询:GET:索引名/_search,入参 ---推荐使用方式

{
  "query":{
    "match":{
      "属性名1""value"
    }
  }
}

查询所有:GET:索引名/_search,入参 ---推荐使用方式

入参区别:match_all

分页查询:

指定返回数据源的属性:

排序:

多条件查询入参:bool

  • must===> AND
  • should===> OR

  • 范围查询:filter

文档修改:

  • 完全修改 PUT:_doc/id
  • 局部修改 POST:_update/id 入参格式变化
{
  "doc":{
    "属性名1":"修改的值1""属性名2":"修改的值2"
  }
}

文档删除:DELETE 索引名/_doc/id

多次删除无效,不会报错,返回结果集中会告知not_found

javaAPI操作

<!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.8.1</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-client -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.8.1</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.8.1</version>
        </dependency>
package com.example.demo.controller.esTest;


import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;

import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
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.AliasMetadata;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;

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

@Slf4j
//@XSlf4j
public class EsTestCOontroller {

    public static void main(String[] args) throws IOException {

        // 创建连接 scheme可不传,不传则使用默认的 默认的是多少呢?一会测试一下
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("124.222.1.237", 9200,
                "http")));

        //创建索引
//        createIndex(client);

        // 删除索引
//        delIndex(client);

        // 查询索引
        getIndex(client);


        // 关闭连接 此处练习先抛出异常
        client.close();
    }

    /**
     * 创建索引
     */
    public static void createIndex(RestHighLevelClient client) throws IOException {
        CreateIndexRequest indexRequest = new CreateIndexRequest("test_two");
        CreateIndexResponse indexResponse = client.indices().create(indexRequest, RequestOptions.DEFAULT);
        log.info("创建响应:{},响应结果标识:{}", JSONObject.toJSONString(indexResponse),indexResponse.isAcknowledged());
    }


    /**
     * 删除索引
     */
    public static void delIndex(RestHighLevelClient client) throws IOException {
        DeleteIndexRequest indexRequest = new DeleteIndexRequest("test");
        AcknowledgedResponse delete = client.indices().delete(indexRequest, RequestOptions.DEFAULT);
        log.info("创建响应:{},响应结果标识:{}", JSONObject.toJSONString(delete),delete.isAcknowledged());

    }


    /**
     * 修改索引:elasticsearch不可 修改索引,只能进行获取原来的index映射再进行针对性的修改,并创建为新index,再将原来的index数据迁移到新index上
     */
    public static void modifyIndex(RestHighLevelClient client) {
        
    }

    /**
     * 查看索引
     */
    public static void getIndex(RestHighLevelClient client) throws IOException {

        GetIndexRequest getIndexRequest = new GetIndexRequest("idx");
        getIndexRequest.includeDefaults(true);
        GetIndexResponse getIndexResponse = client.indices().get(getIndexRequest, RequestOptions.DEFAULT);
    	
        MappingMetadata indexMappings = getIndexResponse.getMappings().get("idx");
        log.info("indexMappings===>:{}", JSONObject.toJSONString(indexMappings));

        Map<String, Object> indexTypeMappings = indexMappings.getSourceAsMap();
        log.info("indexTypeMappings===>:{}", JSONObject.toJSONString(indexTypeMappings));

        List<AliasMetadata> indexAliases = getIndexResponse.getAliases().get("idx");
        log.info("indexAliases===>:{}", JSONObject.toJSONString(indexAliases));

        String numberOfShardsString = getIndexResponse.getSetting("idx", "idx.number_of_shards");
        log.info("numberOfShardsString===>:{}", JSONObject.toJSONString(numberOfShardsString));

        Settings indexSettings = getIndexResponse.getSettings().get("idx");
        log.info("indexSettings===>:{}", indexSettings.toString());

        Integer numberOfShards = indexSettings.getAsInt("idx.number_of_shards", null);
        log.info("numberOfShards===>:{}", JSONObject.toJSONString(numberOfShards));

        TimeValue time = getIndexResponse.getDefaultSettings().get("idx").getAsTime("idx.refresh_interval", null);
        log.info("time===>:{}", JSONObject.toJSONString(time));
    }

}

elasticsearch不可修改index

查询index时遇到的问题:

  1. 不能直接将GetIndexResponse进行jsonToString,否则会报错



@Configuration
//@ConfigurationProperties(prefix = "这里配置什么前缀,则在配置文件中给该类赋值的就必须是该前缀,@Value 属性取值则也是结合这个来取的")
public class EsConfiguration {

    // ip或者dns
    private static String esIp = "124.222.1.237";
	// 端口
    private static int port = 9200;

	// 请求方式
    private static String scheme = "http";

    @Bean
    public  RestHighLevelClient getClient(){
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost(esIp, port,
                scheme)));
        return client;
    }

}



package com.example.demo;

import com.example.demo.configuration.EsConfiguration;
import com.example.demo.controller.esTest.EsDocController;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.io.IOException;

@SpringBootTest
class DemoApplicationTests {

    @Resource
    private EsDocController esDocController;

    @Resource
    private EsConfiguration esConfiguration;

    @Test
    void contextLoads() throws IOException {

        RestHighLevelClient client = esConfiguration.getClient();

        // 插入doc
//        esDocController.insertDoc(client,"lucky");

        // 修改doc 修改不存在的数据会报错 ElasticsearchStatusException
        esDocController.modifyDoc(client,"lucky1","CTyKm4UBkZs9DeCwgnVV");

        // 删除doc 删除不存在的则不会报错,也不会删除该索引下的所有数据
        esDocController.delDoc(client,"lucky","CTyKm4UBkZs9DeCwgnVV");

        //查询doc
        esDocController.selectDoc(client,"lucky","d740bc06-957b-49c1-88b8-a31d9247e63a");

        client.close();
    }


}





package com.example.demo.controller.esTest;


import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.util.DateUtils;
import com.example.demo.configuration.EsConfiguration;
import com.example.demo.docModel.WestDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.stereotype.Controller;
import org.springframework.util.unit.DataUnit;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;


/**
 * ES文档操作
 */
@Slf4j
@Controller
public class EsDocController {


    @Resource
    private EsConfiguration esConfiguration;


    /**
     * 创建索引并插入数据
     * @throws IOException
     */
    public  void createDoc() throws IOException {
        RestHighLevelClient client = esConfiguration.getClient();
        CreateIndexRequest request = new CreateIndexRequest("lucky");

        CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
        // 如果index创建成功则继续创建doc(文档) 正常业务中是先查询如果存在则直接创建数据,如果不存在则创建
        if(Boolean.TRUE.equals(createIndexResponse.isAcknowledged())){
            insertDoc(client,request.index());
        }
        client.close();

    }


    /**
     * 插入数据doc
     * @param client
     * @param index
     * @throws IOException
     */
    public void insertDoc(RestHighLevelClient client,String index) throws IOException {
        // 创建doc过程如下
        IndexRequest indexRequest = new IndexRequest();
        // 如果ID不指定则会自动生成一个
        indexRequest.index(index).id(UUID.randomUUID().toString());
//            indexRequest.index(request.index());
        WestDTO westDTO = WestDTO.builder()
                .age(18)
                .address("重庆渝北区")
                .gender(1)
                .username(index+ System.currentTimeMillis())
                .build();
        String westJson = JSONObject.toJSONString(westDTO);
        indexRequest.source(westJson, XContentType.JSON);

        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        log.info("插入数据成功响应:{}",JSONObject.toJSONString(indexResponse));
    }

    /**
     * 修改doc数据 修改数据需要提前判断数据是否存在,否则会报错
     * @param client
     * @param indexName
     * @param docId
     * @throws IOException
     */
    public  void modifyDoc(RestHighLevelClient client,String indexName,String docId) throws IOException {
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index(indexName).id(docId).doc(XContentType.JSON, "address", "四川省成都市xx区","age", 98);
        UpdateResponse update = client.update(updateRequest, RequestOptions.DEFAULT);
        log.info("修改数据成功响应:{}",JSONObject.toJSONString(update));

    }


    /**
     * 删除数据
     */
    public  void delDoc(RestHighLevelClient client,String indexName,String docId) throws IOException{

        DeleteRequest deleteRequest = new DeleteRequest();
        DeleteRequest id = deleteRequest.index(indexName).id(docId);
        DeleteResponse delete = client.delete(id, RequestOptions.DEFAULT);
        log.info("删除doc===>{}",JSONObject.toJSONString(delete));

    }


    public  void selectDoc(RestHighLevelClient client,String indexName,String docId) throws IOException {

        GetRequest getRequest = new GetRequest();
        getRequest.index(indexName).id(docId);
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
        log.info("查询单个doc===>{}",JSONObject.toJSONString(response));


    }

}