2021-05-17

ElasticSearch安装使用案例

一、Elaticsearch概述

Elaticsearch,简称为es,es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储,检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

多年前,一个叫做Shay Banon的刚结婚不久的失业开发者,由于妻子要去伦敦学习厨师,他便跟着也去了。在他找工作的过程中,为了给妻子构建一个食谱的搜索引擎,他开始构建一个早期版本的Lucene。

直接基于Lucene工作会比较困难,所以Shay开始抽象Lucene代码以便java程序员可以在应用中添加搜索功能。他发布了他的第一个开源项目,叫做“Compass”。

后来Shay找到一份工作,这份工作处理高性能和内存数据网格的分布式环境中,因此高性能的、实时的、分布式的搜索引擎也是理所当然需要的。然后他决定重写Compass库使其成为一个独立的服务器叫做ElasticSearch。

第一个公开版本出现在 2010年2月,在那之后ElasticSearch已经为Github上最受欢迎的项目之一,代码贡献者超过300人。一家主营Elasticsearch的公司就此成立,他们一边提供商业支持一边开发新功能,不过Elasticsearch将永远开源且对所有人可用。

Shay的妻子依旧等待着她的食谱搜索......

二、 ElaticSearch安装

声明:JDK1.8 最低要求,ElasticSearch 客户端,界面工具。

java开发、ElaseticSearch 的版本和我们之后对应的Java的核心jar包,版本对应,JDK环境正常

下载

官网:https://www.elastic.co/cn/

es官网首页

根据自己的操作系统下载对应版本的es

下载地址:https://www.elastic.co/cn/downloads/elasticsearch

es下载页面

 

相关目录说明

 bin 启动文件目录
 config 配置文件目录
     log4j2 日志配置文件
     jvm.options  java 虚拟机相关配置
     elasticsearch.yml   elasticsearch 的配置文件,默认9200端口
 lib 相关jar包
 logs 日志文件
 modules 功能模块
 plugins 插件

linux下安装Elasticsearch

先新建一个用户(出于安全考虑,elasticsearch默认不允许以root账号运行。)

 创建用户:useradd esuser
 设置密码:passwd esuser
 解压:tar -zxvf elasticsearch-7.9.1-linux-x86_64.tar.gz
 ​
 编辑elasticsearch.yml
 修改如下配置
 cluster.name: my-application
 node.name: node-1
 network.host: 192.***.*.**
 http.port: 9200
 cluster.initial_master_nodes: ["node-1"]
 http.cors.enabled: true
 http.cors.allow-origin: "*"

配置文件说明:

es配置文件说明

启动

先将es文件夹下的所有目录的所有权限迭代给esuser用户

 chgrp -R esuser ./es
 chown -R esuser ./es
 chmod 777 es
 ​
 切换到esuser用户启动
  nohup ./bin/elasticsearch & 或 ./bin/elasticsearch

启动成功

es启动

测试

es测试

三、elasticsearch-head安装 、可视化界面(选用)

声明:需要node.js环境

下载地址:https://github.com/mobz/elasticsearch-head

在elasticsearch-head-master目录下

 npm install
 如果以上安装太慢、可用使用npm换一个竟像
 npm install -g cnpm --registry=https://registry.npm.taobao.org
 在执行
 cnpm install

运行启动elasticsearch-head

 grunt server

启动es_head

连接访问

es_head可视化1

查看或新增索引

es_head新增索引

查看索引数据

es_head可视化2

四、kibana安装、可操作界面(选用)

官网:https://www.elastic.co/cn/kibana

kibana官网

声明:kibana版本要和Es版本一致。

下载地址:https://www.elastic.co/cn/downloads/kibana

kibana下载页面

 

解压直接启动

kibana启动

连接访问

kibana页面

五、Elaticsearch 使用介绍

elasticsearch是面向文档 关系行数据库和elasticsearch客观的对比

Relational DBElasticsearch
数据库(database)索引(indices)
表(tables)types
行(rows)documents
字段(columns)fields

elasticsearch(集群)中可用包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)。

物理设计:

elasticsearch在后台把每个索引划分成多个分片,每分分片都可以在集群中的 不同服务器间迁移。

逻辑设计:

一个索引类种中,包含多个文档,比如说文档1,文档2。当我们索引一篇文档时,可以通过这样的一各顺序找到它:索引》类型》文档id,通过这个组合我们就能搜索索引到某个具体的文档。注意:ID不必要整数,实际上它是个字符串。

文档

之前说 eelasticsearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档, elasticsearch中,文档有几个重要属性

  • 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含 keyvalue

  • 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的!

  • 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,elasticsearchl中,对于字段是非常

    灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段

尽管我们可以随意的新增或者忽略某个字段,但是,个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整形,因为 jelasticsearch会保存字段和类型之间的映射及其他的设置。这种映射具体到每个映射的每种类型,这也是为什么在elasticsearch中,类型有时候也称为映射类型

类型

类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器类型中对于字段的定义称为映射,比如name映射为字符串×类型我们文档是无模式的,它们不需要拥有映射中所定义的所有字段,比如新增一个字段,那么 Aelasticsearch是怎么做的呢elasticsearch:会自动的将新字段加入映射,但是这个字段的不确定它是什么类型, elasticsearch就开始猜,如果这个值是18,那么 elasticsearchf会认为它是整形。是 alelasticsearchtt也可能猜不对所以最安全的方式就是提前定义好所需要的映射,这点跟关系型数据库殊途同归了,先定义好字段,然后再使用,别整什么幺蛾子。

索引

索引是映射类型的容器, elasticsearche中的索引是一个非常大的文档集合索引存储了映射类型的字段和其他置,然后它们存储到了各个分片上了。我们来研究下分片是如何工作的。

六、kibana 相关操作

创建索引添加数据:

创建索引

 

创建索引规则

 put /test1
 {
   "mappings":{
     "properties":{
       "name":{
         "type":"text"
       },
       "age":{
         "type":"long"
       },
       "birthday":{
         "type":"date"
       }
     }
   }
 }

获取表信息

 get test1

查看健康值

get _cat/indices

更新数据

POST /test1/_doc/1/_update
{
  "doc":{
    "name":"09fyy"
  }
}

删除

DELETE test1

查询及分页

GET test1/_doc/_search
{
  "query":{
    "match":{
      "name":"09fyy2"
    }
  },
  "sort":[
    {
      "birth":{
        "order":"desc"
      }
    }
    ],
    "from":0,
    "size":1
}

搜索高亮

get testdb/_search
{
  "query":{
    "match": {
      "name": "fyy"
    }
  },
  "highlight":{
    "fields":{
      "name":{}
    }
  }
}

自定义搜索高亮条件

get test1/_search
{
  "query":{
    "match": {
      "name": "fyy"
    }
  },
  "highlight":{
    "pre_tags": "<p class='key' style='color:red'>", "post_tags": "</p>", 
    "fields":{
      "name":{}
    }
  }
}

七、集成JAVA应用

集成SpringBoot开发实例

pom.xml引用相关配置

<?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.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>esmq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>esmq</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.9.1</elasticsearch.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>
        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.2</version>
        </dependency>
        <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.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <version>1.18.10</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

ElasticSearchClientConfig 连接客户端代码

package com.example.esmq;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchClientConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1",9200,"http")));
        return  client;
    }
}

esBean对象

package com.example.esmq;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Content
{

    private String title;
    private String img;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getImg() {
        return img;
    }

    public void setImg(String img) {
        this.img = img;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    private String price;


}

添加数据

/**
	 * 添加数据
	 * @param esBean
	 * @return
	 */
	@Autowired
	private RestHighLevelClient restHighLevelClient;
	public Boolean inserEsData(Content esBean) {
		BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("3m");
        IndexRequest indexRequest = new IndexRequest("senddoc");
        indexRequest.id(esBean.getPrice());
        bulkRequest.add(
        		indexRequest.source(JSON.toJSONString(esBean), XContentType.JSON)
        );
        
        try {
			BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
			 return !bulk.hasFailures();
		} catch (IOException e) {
			
		}
        
		return false;
		
	}

修改数据

/**
	 * 修改数据
	 * @param esBean
	 * @return
	 */
	@Autowired
	private RestHighLevelClient restHighLevelClient;
	public Boolean updataEsData(Content esBean) {
		
		BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("3m");
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index("senddoc");
        updateRequest.id(esBean.getPrice());
        bulkRequest.add(
        		updateRequest.doc(JSON.toJSONString(esBean), XContentType.JSON)
        );
        
	    try {
	    	BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
			return !bulk.hasFailures();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
		return false;
		
	}

删除

/**
	 * 删除数据
	 * @param id 
	 * @return
	 */
	@Autowired
	private RestHighLevelClient restHighLevelClient;
	public Boolean deleteEsData(String id) {
		
		BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("3m");
        DeleteRequest deleteRequest = new DeleteRequest();
        deleteRequest.index("senddoc");
        deleteRequest.id(id);
        bulkRequest.add(deleteRequest);
	    try {
	    	BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
			return !bulk.hasFailures();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
		return false;
		
	}

批量添加数据

/**
	 * 添加数据集
	 * @param esBean
	 * @return
	 */
	@Autowired
	private RestHighLevelClient restHighLevelClient;
	public Boolean arrInserEsData(List<Content> esBean) {
		BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("10m");
        for (int i = 0; i < esBean.size() ; i++) {

        	IndexRequest indexRequest = new IndexRequest("senddoc");
            indexRequest.id(esBean.get(i).getPrice());
            bulkRequest.add(
            		indexRequest.source(JSON.toJSONString(esBean.get(i)), XContentType.JSON)
            );
        }

        try {
			BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
			 return !bulk.hasFailures();
		} catch (IOException e) {
			
		}
        
		return false;
	}

查询es索引数据

@Autowired
private RestHighLevelClient restHighLevelClient;
public List<Map<String, Object>> searchPage(String keyword, int pageNo, int pageSize) throws IOException {
        if(pageNo <= 1){
            pageNo = 1;
        }

        SearchRequest searchRequest = new SearchRequest("jd_goods");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        sourceBuilder.from(pageNo);
        sourceBuilder.size(pageSize);

        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", keyword);
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        List<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit documentFields : searchResponse.getHits().getHits()){
            list.add(documentFields.getSourceAsMap());
        }
        return list;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值