springboot+es创建索引并且插入数据和查询数据

727 阅读2分钟

ElasticSearch是一个分布式、RESTful风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为ES的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。

  • 分布式

    • 集群:同一个业务拓展到很多份

      • 为了增加并发性;集群一定会有负载均衡的前置
    • 分布式:

      • 微服务
      • 不同业务部署到不同地方
  • 分布式一定是集群,集群不一定是分布式

    • 高并发、高可用
    • 我们代码也需要并发优化
  • RESTful风格

    • 所有功能暴露为HTTP请求方式

    • 天然优势?

      • 跨任意语言平台兼容性强 (可以实现多语言兼容,只要发送HTTP请求即可)
    • 搜索和数据分析引擎

      • ES默认存在内存中
      • ES用来搜索个分析。MySQL是为了数据存档(持久化)
      • MySQL存储结构化数据(数据模型固定,基本不会修改)
      • ES可以存储非结构化数据(数据模型不固定)

springboot 配置es @Configuration public class ElasticSearchConfig {

/**
 * 防止netty的bug
 * java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]
 */
@PostConstruct
void init() {
    System.setProperty("es.set.netty.runtime.available.processors", "false");
}

}

连接es服务器

@Configuration
@Slf4j
public class EsConfig {
    @Bean
    RestHighLevelClient restHighLevelClient(@Value("${spring.elasticsearch.hosts}") String hosts) {
        String[] hostsWithPort = hosts.split(",");
        HttpHost[] httpHosts = new HttpHost[hostsWithPort.length];
        for (int i = 0; i < hostsWithPort.length; i++) {
            String hostWithPort = hostsWithPort[i];
            String[] hostPort = hostWithPort.split(":");
            String host = hostPort[0];
            String port = hostPort[1];
            httpHosts[i] = new HttpHost(host, Integer.parseInt(port));
        }
        return new RestHighLevelClient(RestClient.builder(httpHosts));
    }

在代码中引入

@Autowired
    RestHighLevelClient restHighLevelClient;

添加数据操作

public boolean create(@RequestBody SpecialPersonnelAlarm specialPersonnelAlarm) throws Exception {
        //将对象转化为Json串,可以自定义一些转化规则
        String jsonParam = JSONObject.toJSONString(specialPersonnelAlarm,
                SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
        //实体类的id。
        return create(EventConfigKey.INDEX, EventConfigKey.INDEX_TYPE, specialPersonnelAlarm.getId().toString(), jsonParam);
    }
    //传入索引、类型、id和json字符串进行新增操作
    public boolean create(String index, String type, String id, String jsonParam) throws Exception {
        //创建添加数据请求
        IndexRequest indexRequest = new IndexRequest(index, type, id).source(jsonParam, XContentType.JSON);
        try {
            //执行索引请求
            IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
            if (response.status().getStatus() == 201) {
                return true;
            }
        } catch (IOException e) {
            throw new Exception("restClient.create.error");
        }
        return false;
    }

查询数据

public ResponseResult<List> selectRegulatoryWarning(@ApiParam(value = "人员类型") @RequestParam(required = false) String type,
                                                        @ApiParam(value = "日期") @RequestParam(required = false) Date statisticDate) throws IOException {
        //获取年月日
        String yearMonthDayString = DateStringUtils.getYearMonthDayString(statisticDate);
        SearchRequest searchRequest = new SearchRequest(EventConfigKey.INDEX);
        searchRequest.types(EventConfigKey.INDEX_TYPE);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //精确查询and
        if(type!=null&& !type.equals("")){
            QueryBuilder queryBuilder1  = QueryBuilders.termQuery("type", type);
            boolQueryBuilder.must(queryBuilder1);
        }
        QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("statisticDate",yearMonthDayString+"*");
        boolQueryBuilder.must(queryBuilder);
        searchSourceBuilder.query(boolQueryBuilder);
        //根据某个字段排序
        searchSourceBuilder.sort("statisticDate", SortOrder.DESC);
        //将所有的条件进行整合
        searchRequest.source(searchSourceBuilder);
        //根据restHighLevelClient进行查询
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        SearchHit[] hits = searchHits.getHits();
        List list=new ArrayList();
        //获取到实体中的内容
        for (SearchHit hit:hits){
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            sourceAsMap.put("type",specialPersonnelInfoMapper.findConfigName(EventConfigKey.SPEACIAL_PERSONNEL_TYPE,sourceAsMap.get("type").toString()));
            sourceAsMap.put("state",specialPersonnelInfoMapper.findConfigName(EventConfigKey.SPEACIAL_PERSONNEL_STATE,sourceAsMap.get("state").toString()));
            list.add(sourceAsMap);
        }
        return ResponseResult.ok(list);
    }

yml文件配置

spring:
 elasticsearch:
    hosts: ip:9200

自动创建索引

@Autowired
    RestHighLevelClient restHighLevelClient;
    @PostConstruct
    public boolean createIndex() throws IOException {
        String indexName="索引名称";
        GetIndexRequest getIndexRequestrequestTablename = new GetIndexRequest(indexName);
        boolean existsTablename = restHighLevelClient.indices().exists(getIndexRequestrequestTablename, RequestOptions.DEFAULT);
        if (!existsTablename) {
            org.elasticsearch.action.admin.indices.create.CreateIndexRequest request = new org.elasticsearch.action.admin.indices.create.CreateIndexRequest(indexName);
            request.settings(Settings.builder()
                    // 设置分片数为3, 副本为2
                    .put("index.number_of_shards", 3)
                    .put("index.number_of_replicas", 2)
            );
            // 这里创建索引结构
            CreateIndexRequest mapping = request.mapping("type类型名称", generateBuilder());
            CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
            // 指示是否所有节点都已确认请求
            boolean acknowledged = response.isAcknowledged();
            // 指示是否在超时之前为索引中的每个分片启动了必需的分片副本数
            boolean shardsAcknowledged = response.isShardsAcknowledged();
            if (acknowledged || shardsAcknowledged) {
                System.out.println("创建索引成功!索引名称为{}" + indexName);
                return true;
            }
        }else {
            System.out.println("索引已存在");

            return false;
        }
        return existsTablename;
    }

    private XContentBuilder generateBuilder() throws IOException {
        XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.startObject();
        {
            builder.startObject("properties");
            {
                builder.startObject("id");
                {
                    builder.field("type", "integer");
                }
                builder.endObject();
            }
            {
                builder.startObject("addTime");
                {
                    builder.field("type", "date");
                   builder.field("format","yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
                }
                builder.endObject();
            }
            {
                builder.startObject("updateTime");
                {
                    builder.field("type", "date");
                    builder.field("format","yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
                }
                builder.endObject();
            }
            builder.endObject();
        }
        builder.endObject();

        return builder;
    }

pom文件配置

<dependency>
            <!--  ElasticSearch-->
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.1.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>elasticsearch</artifactId>
                    <groupId>org.elasticsearch</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>elasticsearch-rest-client</artifactId>
                    <groupId>org.elasticsearch.client</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <version>2.3.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.plugin</groupId>
            <artifactId>transport-netty4-client</artifactId>
            <version>7.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>7.1.0</version>
        </dependency>

启动类添加

public static void main(String[] args){
        System.setProperty("es.set.netty.runtime.available.processors", "false");
        SpringApplication.run(EventServiceApp.class, args);
    }