Elasticsearch6.5.4集群安装以及与Springboot集成

一、安装

1、拉取镜像

docker pull elasticsearch:6.5.4

2、创建配置及数据目录

 cd /home/frnt/service
 mkdir es
 cd es
 mkdir config
 mkdir data1
 mkdir data2
 mkdir data3

3、创建配置文件

cd config
vi es1.yml
------------------------------------------------------------------------------------------
cluster.name: elasticsearch-cluster
node.name: es-node1
network.bind_host: 0.0.0.0
network.publish_host: 0.0.0.0
http.port: 9200
transport.tcp.port: 9300
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
discovery.zen.ping.unicast.hosts: ["192.168.43.100:9300","192.168.43.100:9301","192.168.43.100:9302"]
discovery.zen.minimum_master_nodes: 2

vi es2.yml
------------------------------------------------------------------------------------------
cluster.name: elasticsearch-cluster
node.name: es-node2
network.bind_host: 0.0.0.0
network.publish_host: 0.0.0.0
http.port: 9201
transport.tcp.port: 9301
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
discovery.zen.ping.unicast.hosts: ["192.168.43.100:9300","192.168.43.100:9301","192.168.43.100:9302"]
discovery.zen.minimum_master_nodes: 2

vi es3.yml
------------------------------------------------------------------------------------------
cluster.name: elasticsearch-cluster
node.name: es-node3
network.bind_host: 0.0.0.0
network.publish_host: 0.0.0.0
http.port: 9202
transport.tcp.port: 9302
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
discovery.zen.ping.unicast.hosts: ["192.168.43.100:9300","192.168.43.100:9301","192.168.43.100:9302"]
discovery.zen.minimum_master_nodes: 2

4、调高jvm线程数限制

vi /etc/sysctl.conf
#添加
vm.max_map_count=655360

#执行生效
sysctl –p

5、启动集群

docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9200:9200 -p 9300:9300 -v /home/frnt/service/es/config/es1.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /home/frnt/service/es/data1:/usr/share/elasticsearch/data --name es01 elasticsearch:6.5.4
    
docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9201:9201 -p 9301:9301 -v /home/frnt/service/es/config/es2.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /home/frnt/service/es/data2:/usr/share/elasticsearch/data --name es02 elasticsearch:6.5.4
    
docker run -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -d -p 9202:9202 -p 9302:9302 -v /home/frnt/service/es/config/es3.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /home/frnt/service/es/data3:/usr/share/elasticsearch/data --name es03 elasticsearch:6.5.4

6、安装elasticsearch-head

#拉取镜像
docker pull mobz/elasticsearch-head:5
#启动elasticsearch-head
docker run --name es-head  -d -p 9100:9100 mobz/elasticsearch-head:5
  • 注意:现在访问elasticsearch-head是不可以的,需要进入容器设置几处。
 #进入容器
 docker exec -it es-head /bin/bash
 #编辑Gruntfile.js
 -----------------------------------------------------------------------------
 connect: {
     server: {
         options: {
             hostname:'*',
             port: 9100,
             base: '.',
             keepalive: true
         }
     }
  }
     
  cd _site
  # 编辑app.js的base_uri,将 localhost 改成 主机IP(192.168.43.100)
  ------------------------------------------------------------------------------
  this.base_uri = this.config.base_uri || this.prefs.get("app-base_uri") || "http://localhost:9200";

退出容器,重启即可访问:http://192.168.43.100:9100/
在这里插入图片描述

7、安装分词器

(1)下载IK分词器
(2)复制到容器plugins下
docker cp elasticsearch-analysis-ik-6.5.4.zip ES01:/usr/share/elasticsearch/plugins/
docker cp elasticsearch-analysis-ik-6.5.4.zip ES02:/usr/share/elasticsearch/plugins/
docker cp elasticsearch-analysis-ik-6.5.4.zip ES03:/usr/share/elasticsearch/plugins/
(3)解压
mkdir ik
mv elasticsearch-analysis-ik-6.5.4.zip ik/
    unzip elasticsearch-analysis-ik-6.5.4.zip
rm -fr elasticsearch-analysis-ik-6.5.4.zip
(4)重启容器即可
 docker restart es01
 docker restart es02
 docker restart es03

二、Springboot集成elasticsearch

以省市区县(area.json)数据为例进行CRUD操作。

1、pom

 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  	<modelVersion>4.0.0</modelVersion>
  	<parent>
  		<groupId>org.springframework.boot</groupId>
  		<artifactId>spring-boot-starter-parent</artifactId>
  		<version>2.0.1.RELEASE</version>
  		<relativePath/> <!-- lookup parent from repository -->
  	</parent>
  
  	<groupId>com.example</groupId>
  	<artifactId>demo</artifactId>
  	<version>0.0.1-SNAPSHOT</version>
  	<name>demo</name>
  	<description>Demo project for Spring Boot</description>
  
  	<properties>
  		<java.version>1.8</java.version>
  	</properties>
  
  	<dependencies>
  		<dependency>
  			<groupId>org.springframework.boot</groupId>
  			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  		</dependency>
  		<dependency>
  			<groupId>org.springframework.boot</groupId>
  			<artifactId>spring-boot-starter-web</artifactId>
  		</dependency>
  
  		<dependency>
  			<groupId>org.projectlombok</groupId>
  			<artifactId>lombok</artifactId>
  			<optional>true</optional>
  		</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>commons-io</groupId>
  			<artifactId>commons-io</artifactId>
  			<version>2.6</version>
  		</dependency>
  	</dependencies>
  
  	<build>
  		<plugins>
  			<plugin>
  				<groupId>org.springframework.boot</groupId>
  				<artifactId>spring-boot-maven-plugin</artifactId>
  			</plugin>
  		</plugins>
  	</build>
  
  </project>

2、vo

package com.example.demo.module;
    
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

@Data
@Document(indexName = "area",type = "docs", shards = 3, replicas = 1)
public class AreaVo {

    /**
     * 区域ID
     */
    @Id
    private Integer areaId;

    /**
     * 区域名称
     */
    @Field(type = FieldType.text, analyzer = "ik_max_word",searchAnalyzer="ik_smart")
    private String areaName;

    /**
     * 父级ID
     */
    @Field(type = FieldType.keyword)
    private Integer parentId;

    /**
     * 地区级别(地区级别(1:省份province,2:市city,3:区县district,4:街道street)
     */
    @Field(type = FieldType.keyword)
    private Integer level;

    /**
     * 城市编码
     */
    @Field(type = FieldType.keyword)
    private String cityCode;

    /**
     * 邮编
     */
    @Field(type = FieldType.keyword)
    private String zipCode;

    /**
     * 简称
     */
    @Field(type = FieldType.text, analyzer = "ik_max_word",searchAnalyzer="ik_smart")
    private String shortName;

    /**
     * 拼音
     */
    @Field(type = FieldType.text, analyzer = "ik_max_word",searchAnalyzer="ik_smart")
    private String pinyin;

    /**
     * 全称
     */
    @Field(type = FieldType.text, analyzer = "ik_max_word",searchAnalyzer="ik_smart")
    private String mergerName;

}

3、ElasticsearchBaseService

package com.example.demo.module;
   
import org.springframework.data.domain.Page;

import java.util.List;

public interface ElasticsearchBaseService<T> {

    List<T> list(int type, String fieldName, String query);

    T save(T t);

    Page<T> page(Integer pageNum, Integer pageSize, int type, String fieldName, String query);

    void delete(T t);

}

4、ElasticsearchSearchService

package com.example.demo.module;
    
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.WildcardQueryBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public abstract  class ElasticsearchSearchService<T> implements ElasticsearchBaseService<T> {

    protected abstract ElasticsearchRepository getBaseRepository();

    /**
     *
     * @param type 类型 1:精确查询,2:模糊查询
     * @param fieldName 查询的字段名称
     * @param query 查询条件
     * @return
     */
    @Override
    public List<T> list(int type, String fieldName, String query) {
        if(type != 1 && type != 2){
            throw new IllegalArgumentException("非法入参");
        }
        //模糊匹配
        if(type == 2){
            query=matchString(query);
        }
        WildcardQueryBuilder queryBuilder = QueryBuilders.wildcardQuery(fieldName, query);
        Iterable<T> search = getBaseRepository().search(queryBuilder);
        List<T> list=new ArrayList<>();
        Iterator<T> iterator = search.iterator();
        while (iterator.hasNext()){
            list.add(iterator.next());
        }
        return list;
    }

    /**
     * 添加索引(包含更新)
     * @param t
     * @return
     */
    @Override
    public T save(T t){
        return (T) getBaseRepository().save(t);
    }

    /**
     * 分页查询
     * @param pageNum 起始页
     * @param pageSize
     * @param type 类型 1:精确查询,2:模糊查询
     * @param fieldName 查询的字段名称
     * @param query 查询条件
     * @return
     */
    @Override
    public Page<T> page(Integer pageNum, Integer pageSize,int type,String fieldName, String query) {

        if(type != 1 && type != 2){
            throw new IllegalArgumentException("非法入参");
        }
        if(pageNum == null){
            pageNum = 0;
        }
        if(pageSize == null){
            pageSize=20;
        }
        //模糊匹配
        if(type == 2){
            query=matchString(query);
        }
        WildcardQueryBuilder queryBuilder = QueryBuilders.wildcardQuery(fieldName, query);
        return getBaseRepository().search(queryBuilder, PageRequest.of(pageNum,pageSize));
    }

    /**
     * 删除
     * @param t
     */
    @Override
    public void delete(T t){
        getBaseRepository().delete(t);
    }

    protected String matchString(String str){
        return "*".concat(str).concat("*");
    }
}

5、AreaRepository

package com.example.demo.module;
    
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface AreaRepository extends ElasticsearchRepository<AreaVo,Integer> {
}

6、AreaService

package com.example.demo.module;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Service;

@Service
public class AreaService extends ElasticsearchSearchService<AreaVo>{

   @Autowired
   private AreaRepository AreaRepository;

   @Override
   public ElasticsearchRepository getBaseRepository() {
       return AreaRepository;
   }
}

7、AreaController

package com.example.demo.module;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/area")
public class AreaController {

    @Autowired
    private AreaService areaService;

    @RequestMapping("/list")
    public List<AreaVo> list(@RequestParam("fieldName") String fieldName, @RequestParam("query") String query){
        return areaService.list(2, fieldName, query);
    }

    @RequestMapping("/save")
    public void save(@RequestBody AreaVo areaVo) {
        areaService.save(areaVo);
    }

    @RequestMapping("/page")
    public Page<AreaVo> page(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize, @RequestParam("fieldName") String fieldName, @RequestParam("query") String query){
        return areaService.page(pageNum, pageSize, 2, fieldName, query);
    }

    @RequestMapping("/delete")
    public void delete(@RequestBody AreaVo areaVo) {
        areaService.delete(areaVo);
    }

}

8.area.json样例

{
  "RECORDS": [
    {
      "area_id": "100000",
      "area_name": "中国",
      "parent_id": "0",
      "short_name": "中国",
      "level": "0",
      "city_code": "",
      "zip_code": "",
      "merger_name": "中国",
      "pinyin": "China"
    },
    {
      "area_id": "110000",
      "area_name": "北京",
      "parent_id": "100000",
      "short_name": "北京",
      "level": "1",
      "city_code": "",
      "zip_code": "",
      "merger_name": "北京",
      "pinyin": "Beijing"
    },
    {
      "area_id": "110100",
      "area_name": "北京市",
      "parent_id": "110000",
      "short_name": "北京",
      "level": "2",
      "city_code": "010",
      "zip_code": "100000",
      "merger_name": "北京,北京市",
      "pinyin": "Beijing"
    },
    {
      "area_id": "110101",
      "area_name": "东城区",
      "parent_id": "110100",
      "short_name": "东城",
      "level": "3",
      "city_code": "010",
      "zip_code": "100010",
      "merger_name": "北京,北京市,东城区",
      "pinyin": "Dongcheng"
    },
    {
      "area_id": "110102",
      "area_name": "西城区",
      "parent_id": "110100",
      "short_name": "西城",
      "level": "3",
      "city_code": "010",
      "zip_code": "100032",
      "merger_name": "北京,北京市,西城区",
      "pinyin": "Xicheng"
    },
    {
      "area_id": "110105",
      "area_name": "朝阳区",
      "parent_id": "110100",
      "short_name": "朝阳",
      "level": "3",
      "city_code": "010",
      "zip_code": "100020",
      "merger_name": "北京,北京市,朝阳区",
      "pinyin": "Chaoyang"
    },
    {
      "area_id": "110106",
      "area_name": "丰台区",
      "parent_id": "110100",
      "short_name": "丰台",
      "level": "3",
      "city_code": "010",
      "zip_code": "100071",
      "merger_name": "北京,北京市,丰台区",
      "pinyin": "Fengtai"
    },
    {
      "area_id": "110107",
      "area_name": "石景山区",
      "parent_id": "110100",
      "short_name": "石景山",
      "level": "3",
      "city_code": "010",
      "zip_code": "100043",
      "merger_name": "北京,北京市,石景山区",
      "pinyin": "Shijingshan"
    },
    {
      "area_id": "110108",
      "area_name": "海淀区",
      "parent_id": "110100",
      "short_name": "海淀",
      "level": "3",
      "city_code": "010",
      "zip_code": "100089",
      "merger_name": "北京,北京市,海淀区",
      "pinyin": "Haidian"
    },
    {
      "area_id": "110109",
      "area_name": "门头沟区",
      "parent_id": "110100",
      "short_name": "门头沟",
      "level": "3",
      "city_code": "010",
      "zip_code": "102300",
      "merger_name": "北京,北京市,门头沟区",
      "pinyin": "Mentougou"
    },
    {
      "area_id": "110111",
      "area_name": "房山区",
      "parent_id": "110100",
      "short_name": "房山",
      "level": "3",
      "city_code": "010",
      "zip_code": "102488",
      "merger_name": "北京,北京市,房山区",
      "pinyin": "Fangshan"
    },
    {
      "area_id": "110112",
      "area_name": "通州区",
      "parent_id": "110100",
      "short_name": "通州",
      "level": "3",
      "city_code": "010",
      "zip_code": "101149",
      "merger_name": "北京,北京市,通州区",
      "pinyin": "Tongzhou"
    },
    {
      "area_id": "110113",
      "area_name": "顺义区",
      "parent_id": "110100",
      "short_name": "顺义",
      "level": "3",
      "city_code": "010",
      "zip_code": "101300",
      "merger_name": "北京,北京市,顺义区",
      "pinyin": "Shunyi"
    },
    {
      "area_id": "110114",
      "area_name": "昌平区",
      "parent_id": "110100",
      "short_name": "昌平",
      "level": "3",
      "city_code": "010",
      "zip_code": "102200",
      "merger_name": "北京,北京市,昌平区",
      "pinyin": "Changping"
    },
    {
      "area_id": "110115",
      "area_name": "大兴区",
      "parent_id": "110100",
      "short_name": "大兴",
      "level": "3",
      "city_code": "010",
      "zip_code": "102600",
      "merger_name": "北京,北京市,大兴区",
      "pinyin": "Daxing"
    },
    {
      "area_id": "110116",
      "area_name": "怀柔区",
      "parent_id": "110100",
      "short_name": "怀柔",
      "level": "3",
      "city_code": "010",
      "zip_code": "101400",
      "merger_name": "北京,北京市,怀柔区",
      "pinyin": "Huairou"
    },
    {
      "area_id": "110117",
      "area_name": "平谷区",
      "parent_id": "110100",
      "short_name": "平谷",
      "level": "3",
      "city_code": "010",
      "zip_code": "101200",
      "merger_name": "北京,北京市,平谷区",
      "pinyin": "Pinggu"
    },
    {
      "area_id": "110228",
      "area_name": "密云县",
      "parent_id": "110100",
      "short_name": "密云",
      "level": "3",
      "city_code": "010",
      "zip_code": "101500",
      "merger_name": "北京,北京市,密云县",
      "pinyin": "Miyun"
    },
    {
      "area_id": "110229",
      "area_name": "延庆县",
      "parent_id": "110100",
      "short_name": "延庆",
      "level": "3",
      "city_code": "010",
      "zip_code": "102100",
      "merger_name": "北京,北京市,延庆县",
      "pinyin": "Yanqing"
    }]
}    

总结

查询中发现,有些完整的词搜索不到,拆解分别查询都可以查到,比如:使用“海州”去查询是查不到的,但是如果使用“海”或“州”都可以查询到“海州”。因为是分词把“海州”分成了“海”和“州”两个,所以使用“海州”搜索不到。
分词情况:http://192.168.43.100:9200/_analyze/?pretty
参数:{ "analyzer": "ik_max_word", "text": "海州" }
结果:{ "tokens": [ { "token": "海", "start_offset": 0, "end_offset": 1, "type": "CN_CHAR", "position": 0 }, { "token": "州", "start_offset": 1, "end_offset": 2, "type": "CN_CHAR", "position": 1 } ] }

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值