天天看点

ES安装、SpringBoot集成ES

一、安装ES

下载ES包,去官网下载页可以:

#大约280M
链接:https://pan.baidu.com/s/1LaWlIwrI7UxVEdytoD1JWw 
提取码:6p0j
           
压缩包上传到/usr/local目录下
tar -xzvf elasticsearch-7.5.0-linux-x86_64.tar.gz
adduser es
#赋予文件夹权限
chown -R es /usr/local/elasticsearch-7.5.0/
#切换用户
su es
/usr/local/elasticsearch-7.5.0/bin/elasticsearch -d #-d 在后台以守护进程模式运行
           
#校验运行情况,出现下图则代表启动成功:
netstat -lntp
curl 'http://localhost:9200/?pretty'
           
ES安装、SpringBoot集成ES

二、简单配置ES

#修改配置文件
vi /usr/local/elasticsearch-7.5.0/config/elasticsearch.yml
           
# Use a descriptive name for your cluster:
# 起的名字
cluster.name: big-data
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
# 节点名字
node.name: node-1
#

#
# Set the bind address to a specific IP (IPv4 or IPv6):
# 当前主节点的host
network.host: 123.57.133.22
#当前局域网节点 单机es则配置127.0.0.1
transport.host: 127.0.0.1
#网络限制ip  当前配置不做任何限制,任何ip都能访问当前es
http.host: 0.0.0.0
#
# Set a custom port for HTTP:
# 端口,默认也为9200
http.port: 9200
           

三、一般报错处理

1、max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]

每个进程最大同时打开文件数太小,可通过下面2个命令查看当前数量

ulimit -Hn
ulimit -Sn

修改/etc/security/limits.conf文件,增加配置,用户退出后重新登录生效

*               soft    nofile          65536
*               hard    nofile          65536
           

2、max number of threads [3818] for user [es] is too low, increase to at least [4096]

问题同上,最大线程个数太低。修改配置文件/etc/security/limits.conf(和问题1是一个文件),增加配置
*               soft    nproc           4096
*               hard    nproc           4096
#可通过命令查看
ulimit -Hu
ulimit -Su
           

3、max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

 修改/etc/sysctl.conf文件,增加配置vm.max_map_count=262144
vi /etc/sysctl.conf
sysctl -p  #执行命令sysctl -p生效
           

4、Exception in thread “main” java.nio.file.AccessDeniedException: /usr/local/elasticsearch/elasticsearch-6.2.2-1/config/jvm.options

  elasticsearch用户没有该文件夹的权限,执行命令

chown -R es:es /usr/local/elasticsearch/
           

四、springBoot集成ES

1. 引入maven

<!--es依赖   -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.5.0</version>
            <scope>compile</scope>
        </dependency>
           

2.配置application.properties或yml文件

elasticsearch.user:   #用户 未设置则空
elasticsearch.password:   #密码 未设置则空
elasticsearch.host: 123.57.xx.xx:9200    #ip和端口号
           

3.简单新增操作

/**
     * 添加
     * @return
     */
    @RequestMapping(value="add",method = RequestMethod.POST)
    public void add( ){

        String index = "my_index";
        try {
            for(int i=0;i<20;i++) {
                XContentBuilder builder = XContentFactory.jsonBuilder()
                        .startObject()
                        .field("id", i+"")
                        .field("content", "内容"+i)
                        .field("age",(20+i)+"")
                        .endObject();
                String id = ESUtil.addData(builder, index, i+"");
                logger.info("插入一条数据,id为{}",i);
            }
        } catch (IOException e) {
             e.printStackTrace();
        }
    }
           

4.简单删除操作

/**
     * 删除
     * @return
     */
    @RequestMapping(value="delete",method = RequestMethod.POST)
    @ResponseBody
    public String delete(@RequestParam String id){

        String index = "my_index";
        //根据id删除
        String status = ESUtil.deleteById(index, id);
        //打印查询结果
        return "success";
    }
           

5.简单修改操作

/**
     * 更新
     * @return
     */
    @RequestMapping(value="update",method = RequestMethod.POST)
    public String update(@RequestParam String id)throws  Exception{

        String index = "my_index";
        XContentBuilder builder =XContentFactory.jsonBuilder()
                .startObject()
                .field("id",id)
                .field("content","这是内容"+id)
                .field("age",id).endObject();
        String responseId = ESUtil.updateData(builder, index, id);
        logger.info("打印更新的id"+responseId);
        //打印查询结果
        return responseId;
    }
           

6.简单查询操作

/**
     * 分页+条件查询
     * @return
     */
    @RequestMapping(value="get",method = RequestMethod.POST)
    public void get( ){

        String index = "my_index";
        //分页+条件查询
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.matchQuery("content","内容2"));
        SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
        List<Map<String, Object>> list = ESUtil.SearchDataPage(index, 1, 20, sourceBuilder, builder);
        //打印查询结果
        System.out.println(list);
    }
           

7.上面代码用到的工具类

ESUtil

package com.example.util;

import com.example.pojo.EsEntity;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
public class ESUtil {

    private static final Logger log = LoggerFactory.getLogger(ESUtil.class);
    @Qualifier("highLevelClient")
    @Autowired
    private RestHighLevelClient rhlClient;

    private static RestHighLevelClient client;

    /**
     * spring容器初始化的时候执行该方法
     */
    @PostConstruct
    public void init() {
        client = this.rhlClient;
    }

    /**
     * 添加数据
     *
     * @param content 数据内容
     * @param index   索引
     * @param id      id
     */
    public static String addData(XContentBuilder content, String index, String id) {
        String Id = null;
        try {
            IndexRequest request = new IndexRequest(index).id(id).source(content);
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);
            Id = response.getId();
            log.info("索引:{},数据添加,返回码:{},id:{}", index, response.status().getStatus(), Id);
        } catch (IOException e) {
            log.error("添加数据失败,index:{},id:{}", index, id);
        }
        return Id;
    }

    /**
     * 修改数据
     *
     * @param content 修改内容
     * @param index   索引
     * @param id      id
     */
    public static String updateData(XContentBuilder content, String index, String id) {
        String Id = null;
        try {
            UpdateRequest request = new UpdateRequest(index, id).doc(content);
            UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
            Id = response.getId();
            log.info("数据更新,返回码:{},id:{}", response.status().getStatus(), Id);
        } catch (IOException e) {
            log.error("数据更新失败,index:{},id:{}", index, id);
        }
        return Id;
    }

    /**
     * 批量插入数据
     *
     * @param index 索引
     * @param list  批量增加的数据
     */
    public static String insertBatch(String index, List<EsEntity> list) {
        String state = null;
        BulkRequest request = new BulkRequest();
        list.forEach(item -> request.add(new IndexRequest(index)
                .id(item.getId()).source(JsonUtils.toJson(item.getData()), XContentType.JSON)));
        try {
            BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
            int status = bulk.status().getStatus();
            state = Integer.toString(status);
            log.info("索引:{},批量插入{}条数据成功!", index, list.size());
        } catch (IOException e) {
            log.error("索引:{},批量插入数据失败", index);
        }
        return state;
    }

    /**
     * 根据条件删除数据
     *
     * @param index   索引
     * @param builder 删除条件
     */
    public static void deleteByQuery(String index, QueryBuilder builder) {
        DeleteByQueryRequest request = new DeleteByQueryRequest(index);
        request.setQuery(builder);
        //设置此次删除的最大条数
        request.setBatchSize(1000);
        try {
            client.deleteByQuery(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("根据条件删除数据失败,index:{}", index);
        }
    }

    /**
     * 根据id删除数据
     *
     * @param index 索引
     * @param id    id
     */
    public static String deleteById(String index, String id) {
        String state = null;
        DeleteRequest request = new DeleteRequest(index, id);
        try {
            DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
            int status = response.status().getStatus();
            state = Integer.toString(status);
            log.info("索引:{},根据id{}删除数据:{}", index, id, JsonUtils.toJson(response));
        } catch (IOException e) {
            log.error("根据id删除数据失败,index:{},id:{}", index, id);
        }
        return state;
    }


    /**
     * 根据条件查询数据
     *
     * @param index         索引
     * @param startPage     开始页
     * @param pageSize      每页条数
     * @param sourceBuilder 查询返回条件
     * @param queryBuilder  查询条件
     */
    public static List<Map<String, Object>> SearchDataPage(String index, int startPage, int pageSize,
                                                           SearchSourceBuilder sourceBuilder, QueryBuilder queryBuilder) {
        SearchRequest request = new SearchRequest(index);
        //设置超时时间
        sourceBuilder.timeout(new TimeValue(120, TimeUnit.SECONDS));
        //设置是否按匹配度排序
        sourceBuilder.explain(true);
        //加载查询条件
        sourceBuilder.query(queryBuilder);
        //设置分页
        sourceBuilder.from((startPage - 1) * pageSize).size(pageSize);
        log.info("查询返回条件:" + sourceBuilder.toString());
        request.source(sourceBuilder);
        try {
            SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
            long totalHits = searchResponse.getHits().getTotalHits().value;
            log.info("共查出{}条记录", totalHits);
            RestStatus status = searchResponse.status();
            if (status.getStatus() == 200) {
                List<Map<String, Object>> sourceList = new ArrayList<>();
                for (SearchHit searchHit : searchResponse.getHits().getHits()) {
                    Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
                    sourceList.add(sourceAsMap);
                }
                return sourceList;
            }
        } catch (IOException e) {
            log.error("条件查询索引{}时出错", index);
        }
        return null;
    }

}

           

用到的EsEntity

package com.example.pojo;
public class EsEntity {
    private String id;
    private Object data;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}
           

用到的JsonUtils

package com.example.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author xiaolang
 * @version 1.0.0
 */
public class JsonUtils {
    private static Logger logger = LoggerFactory.getLogger(JsonUtils.class);
    private static final ObjectMapper objectMapper;
    static {
        objectMapper = new ObjectMapper();
        //去掉默认的时间戳格式
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        //设置为中国上海时区
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
//        objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
        //空值不序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //反序列化时,属性不存在的兼容处理
        objectMapper.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        //序列化时,日期的统一格式
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //单引号处理
        objectMapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

    }

    public static <T> T toObject(String json, Class<T> clazz) {
        try {
            return objectMapper.readValue(json, clazz);
        } catch (JsonParseException e) {
            logger.error(e.getMessage(), e);
        } catch (JsonMappingException e) {
            logger.error(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    public static <T> String toJson(T entity) {
        try {
            return objectMapper.writeValueAsString(entity);
        } catch (JsonGenerationException e) {
            logger.error(e.getMessage(), e);
        } catch (JsonMappingException e) {
            logger.error(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    public static <T> T toCollection(String json, TypeReference<T> typeReference) {
        try {
            return objectMapper.readValue(json, typeReference);
        } catch (JsonParseException e) {
            logger.error(e.getMessage(), e);
        } catch (JsonMappingException e) {
            logger.error(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * json string convert to map
     */
    public static <T> Map<String, Object> json2map(String jsonStr)
            throws Exception {
        return objectMapper.readValue(jsonStr, Map.class);
    }

    /**
     * json string convert to map with javaBean
     */
    public static <T> Map<String, T> json2map(String jsonStr, Class<T> clazz)
            throws Exception {
        Map<String, Map<String, Object>> map = objectMapper.readValue(jsonStr,
                new TypeReference<Map<String, T>>() {
                });
        Map<String, T> result = new HashMap<String, T>();
        for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
        }
        return result;
    }

    /**
     * json array string convert to list with javaBean
     */
    public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz)
            throws Exception {
        List<Map<String, Object>> list = objectMapper.readValue(jsonArrayStr,
                new TypeReference<List<T>>() {
                });
        List<T> result = new ArrayList<T>();
        for (Map<String, Object> map : list) {
            result.add(map2pojo(map, clazz));
        }
        return result;
    }

    /**
     * map convert to javaBean
     */
    public static <T> T map2pojo(Map map, Class<T> clazz) {
        return objectMapper.convertValue(map, clazz);
    }

}