Elasticsearch的基本使用


官网:https://www.elastic.co/cn
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
官方中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html
社区中文:
https://es.xiaoleilu.com/index.html
http://doc.codingdict.com/elasticsearch/0/

1、什么是Elasticsearch

Elasticsearch 是一个分布式的免费开源搜索和分析引擎,适用于包括文本、数字、地理空间、结构化和非结构化数据等在内的所有类型的数据。Elasticsearch 在 Apache Lucene 的基础上开发而成,由 Elasticsearch N.V.(即现在的 Elastic)于 2010 年首次发布。Elasticsearch 以其简单的 REST 风格 API、分布式特性、速度和可扩展性而闻名,是 Elastic Stack 的核心组件;Elastic Stack 是一套适用于数据采集、扩充、存储、分析和可视化的免费开源工具。人们通常将 Elastic Stack 称为 ELK Stack(代指 Elasticsearch、Logstash 和 Kibana),目前 Elastic Stack 包括一系列丰富的轻量型数据采集代理,这些代理统称为 Beats,可用来向 Elasticsearch 发送数据。

2、Elasticsearch 的用途

应用程序搜索
网站搜索
企业搜索
日志处理和分析
基础设施指标和容器监测
应用程序性能监测
地理空间数据分析和可视化
安全分析
业务分析

3、基本概念

6.0以后不建议设置类型
1、Index(索引)相当mysql中的数据库
动词,相当于 MySQL 中的 insert;
名词,相当于 MySQL 中的 Database
2、Type(类型) 相当于mysql中表
在 Index(索引)中,可以定义一个或多个类型。
类似于 MySQL 中的 Table;每一种类型的数据放在一起;
3、Document(文档)相当于mysql中的一条数据
保存在某个索引(Index)下,某种类型(Type)的一个数据(Document),文档是 JSON 格
式的,Document 就像是 MySQL 中的某个 Table 里面的内容;
在es中所有的数据都是一个json的文档

4、Docker安装elasticsearch

##redis安装#########################################################end####

##elasticsearch安装#########################################################start####
## 存储和检索数据
docker pull elasticsearch:7.4.2 
## 可视化检索数据
docker pull kibana:7.4.2 
## 获取最高权限
su root
vagrant

## 创建config文件夹
mkdir -p /mydata/elasticsearch/config
## 创建数据文件夹
mkdir -p /mydata/elasticsearch/data
## 配置文件,容许所有的ip访问elasticsearch
echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml
## 保证权限,将任何用户在/mydata/elasticsearch/ 下都有可读可写可执行的权限 -R递归
chmod -R 777 /mydata/elasticsearch/ 
##  --name 为容器起一个名字叫 elasticsearch
##  -p 9200:9200 -p 9300:9300  暴漏两个端口
## \ 换行
## -e 设置参数 ES_JAVA_OPTS="-Xms64m -Xmx256m" \ 测试环境下,设置 ES 的初始内存和最大内存,否则导
##致过大启动不了 ES
## -v 挂在以后在linux下的目录中就可以修改和获取到mysql内部的数据。
## -d 启动容器用的哪个镜像
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
## 查看日志
docker logs elasticsearch
## 可视化界面Kibana 的安装
## http://192.168.56.10:9200 一定改为自己虚拟机的地址
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 \
-d kibana:7.4.2

##elasticsearch安装#########################################################end######

查看当前IP地址:ip addr
在这里插入图片描述

4.1 测试elasticsearch是否启动成功:http://192.168.56.10:9200/

在这里插入图片描述

4.2 测试可视化工具kibana是否启动成功:http://192.168.56.10:5601

在这里插入图片描述

5、初步检索

查看版本:http://192.168.56.10:9200/

在这里插入图片描述

带“_”的都表示元数据

5.1 _cat

GET /_cat/nodes:查看所有节点
GET /_cat/health:查看 es 健康状况
GET /_cat/master:查看主节点
GET /_cat/indices:查看所有索引 show databases;

5.2 索引一个文档(保存)

保存文档有两种方式,1 put, 2 post

PUT customer/external/1
{ "name": "John Doe"
}
POST customer/external/2

注意事项

PUT 和 POST 都可以保存,
POST 新增。如果不指定 id,会自动生成 id。指定 id 就会修改这个数据,并新增版本号
PUT 可以新增可以修改。PUT 必须指定 id;由于 PUT 需要指定 id,我们一般都用来做修改
操作,不指定 id 会报错。

在这里插入图片描述

5.3 查询文档

GET customer/external/1

结果:

{ "_index": "customer", //在哪个索引
"_type": "external", //在哪个类型
"_id": "1", //记录 id
"_version": 2, //版本号
"_seq_no": 1, //并发控制字段,每次更新就会+1,用来做乐观锁
"_primary_term": 1, //同上,主分片重新分配,如重启,就会变化
"found": true, "_source": { //真正的内容
"name": "John Doe"
}
}

5.4 乐观锁的使用

“_seq_no”: 1, //并发控制字段,每次更新就会+1,用来做乐观锁
“_primary_term”: 1, //同上,主分片重新分配,如重启,就会变化

更新携带 ?if_seq_no=0&if_primary_term=1
例:
http://192.168.56.10:9200/customer/external/1?if_seq_no=1&if_primary_term=1

5.5 更新文档

方式1:post + _update
http://192.168.56.10:9200/customer/external/2/_update

{"doc":{ 
    "name": "John Doe111"
}}

方式2:put或post
http://192.168.56.10:9200/customer/external/2

{ 
    "name": "John Doe"
}

不同:

POST 操作会对比源文档数据,如果相同不会有什么操作,文档 version 不增加
PUT 操作总会将数据重新保存并增加 version 版本;
带_update 对比元数据如果一样就不进行任何操作。
	看场景;
	对于大并发更新,不带 update;
	对于大并发查询偶尔更新,带 update;对比更新,重新计算分配规则。

更新同时增加属性

POST customer/external/1/_update
{ "doc": { "name": "Jane Doe", "age": 20 }
}
PUT 和 POST 不带_update 也可以

5.6 删除

## 删除文档
delete	http://192.168.56.10:9200/customer/external/1
## 把索引删除
delete	http://192.168.56.10:9200/customer
## 不能只删除类型

5.7 bulk 批量 API

POST customer/external/_bulk
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }

语法格式:

{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n

简单实例:

POST  customer/external/_bulk
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }

在这里插入图片描述
复杂实力
POST customer/external/_bulk

{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}{ "title": "My first blog post" }
{ "index": { "_index": "website", "_type": "blog" }}{ "title": "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123"} }
{ "doc" : {"title" : "My updated blog post"} }

在这里插入图片描述

5.8 样本测试数据

我准备了一份顾客银行账户信息的虚构的 JSON 文档样本。每个文档都有下列的 schema
(模式):

{ "account_number": 0, "balance": 16623, "firstname": "Bradshaw", "lastname": "Mckenzie", "age": 29, "gender": "F", "address": "244 Columbus Place", "employer": "Euron", "email": "bradshawmckenzie@euron.com", "city": "Hobucken", "state": "CO"
}

https://github.com/elastic/elasticsearch/blob/master/docs/src/test/resources/accounts.json?raw
=true

POST bank/account/_bulk
测试数据

进阶检索

6、SearchAPI

ES 支持两种基本方式检索 :

  • 一个是通过使用 REST request URI 发送搜索参数(uri+检索参数)
  • 另一个是通过使用 REST request body 来发送它们(uri+请求体),推荐使用第二种
GET bank/_search?q=*&sort=account_number:desc

GET bank/_search
{
"query": {
  "match_all": {}
},
"sort": [
  {
    "account_number": {
      "order": "desc"
    },
    "balance":{
      "order": "asc"
    }
  }
]
}

6.1 match ,match_all,multi_match ,must_not, should 的使用

match 分词配置
match_all 匹配所有
must_not 不配置
multi_match 多字段匹配
should 此条件如果成立会增加max_score的值

## 全文检索会按照评分进行排序,会对检索条件进行分词匹配
GET bank/_search
{
  "query": {
   "match": {
     "address": "mill road"
   }
  }
}

## 短语匹配
GET bank/_search
{
  "query": {
   "match_phrase": {
     "address": "mill road"
   }
  }
}


## 多字段配置
GET bank/_search
{
  "query": {
   "multi_match": {
     "query": "mill movico",
     "fields": ["address","city"]
   }
  }
}

6.2 filter的使用

## 复合查询
GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "gender": "m"
        }}
      ],
      "must_not": [
        {"match": {
          "age": "32"
        }}
      ],
      "should": [
        {"match": {
          "lastname": "Bond"
        }}
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 18,
            "lte": 30
          }
        }
      }
    }
  }
}

6.2 must he should,filter的区别

## must he should 会贡献相关性得分
GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {"range": {
          "age": {
            "gte": 18,
            "lte": 30
          }
        }}
      ]
    }
  }
}


## filter 不会计算相关性得分
GET bank/_search
{
  "query": {
    "bool": {
      "filter": [
        {"range": {
          "age": {
            "gte": 18,
            "lte": 30
          }
        }}
      ]
    }
  }
}

6.3 term的使用

term 和 match 一样。匹配某个属性的值。全文检索字段用 match,其他非 text 字段匹配用 term。

## term 和 match 一样。匹配某个属性的值。全文检索字段用 match,其他非 text 字段匹配用 term。
GET bank/_search
{
  "query": {
    "term": {
      "age": {
        "value": 28
      }
    }
  }
}

6.4 keyword 精确匹配

## 精确匹配
GET bank/_search
{
  "query": {
    "match": {
      "address.keyword": "Rutledge Street"
    }
  }
}

6.5 符合查询 bool

## 复合查询
## 查询性别为m并且地址中包含 mill的数据
GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "gender": "m"
        }},
        {
          "match": {
            "address": "mill"
          }
        }
      ]
    }
  }
}

## 复合查询
## 查询处性别为m并且年龄在18到30之间的病情年龄不能为32的
GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {
          "gender": "m"
        }}
      ],
      "must_not": [
        {"match": {
          "age": "20"
        }}
      ],
      "should": [
        {"match": {
          "lastname": "Bond"
        }}
      ],
      "filter": {
        "range": {
          "age": {
            "gte": 18,
            "lte": 30
          }
        }
      }
    }
  }
}

6.6 聚合查询

## 聚合此操作
## 搜索address中包含mill的所有人的年龄分布以及平均年龄
GET bank/_search
{
  "query": {
    "match": {
      "address": "mill"
    }
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 10
      }
    },
    "ageAvg":{
      "avg": {
        "field": "age"
      }
    },
    "balanceAvg":{
      "avg": {
        "field": "balance"
      }
    }
  },
  "size": 0
}

## 聚合操作
## 按照年龄聚合,并且请求这些年龄段的这些人的平局薪资
GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "ageAvg": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  },
  "size": 0
}


## 聚合操作
## 查出所有年龄分布,并且这些年龄端中性别M,F的平均年薪以及这个年龄段性别的总体平均年薪
GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "genderAgg": {
          "terms": {
            "field": "gender.keyword",
            "size": 10
          },
          "aggs": {
            "ageAgg": {
              "avg": {
                "field": "balance"
              }
            }
          }
        },
        "ageGenderAgg":{
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  },
  "size": 1
}

6.7 数据迁移

Es7 及以上移除了 type 的概念。
将已存在的索引下的类型数据,全部迁移到指定位置即可。
第一步:创建映射

PUT /my-index
{ "mappings": { "properties": {"age": { "type": "integer" }, "email": { "type": "keyword" }, "name": { "type": "text" }
}
}
}

第二步:添加新的字段映射

PUT /my-index/_mapping
{ "properties": { "employee-id": { "type": "keyword", "index": false
}
}
}

第三步:更新映射
对于已经存在的映射字段,我们不能更新。更新必须创建新的索引进行数据迁移
第四步:数据迁移
先创建出 new_twitter 的正确映射。然后使用如下方式进行数据迁移

POST _reindex [固定写法]
{ "source": { "index": "twitter"
},"dest": { "index": "new_twitter"
}
}

将旧索引的 type 下的数据进行迁移

POST _reindex
{ "source": {"index": "twitter", "type": "tweet"
},"dest": { "index": "tweets"
}
}

7、安装ik中文分词库,以及使用xshell和xftp工具

第一步:修改Vagrant的密码登录功能

 vi /etc/ssh/sshd_config

修改:PasswordAuthentication no 为 PasswordAuthentication yes 并保存推出
第二步:重启ssh服务

service sshd restart

在这里插入图片描述
第三步:通过xshell连接linux服务器
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第四步:通过xft上传文件并解压程序
在这里插入图片描述
由于做了挂在,所在在elasticsearch内部的文件夹下也是可以看到的。
在这里插入图片描述
第五步:修改ik文件夹的读写可执行权限

chmod -R 777  /mydata/elasticsearch/plugins/ik/
ll

在这里插入图片描述
第六步:查看elasticsearch的插件列表

docker exec -it 610d /bin/bash
cd bin
elasticsearch-plugin list

返回ik 表示插件安装成功

第六步: 重启elasticsearch
在这里插入图片描述
第七步:测试
重启elasticsearch后,刷新一下kibana页面

## 分词
## 标准分词器,es中默认的分词器支持的时英文的分词,对于中文的分词我们需要额外的安装自己的分词器
## 中文分词器:ik分词器下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v7.4.2
## 注意由于我们的es版本时7.4.2 所以ik分词器的版本也要是7.4.2
POST _analyze
{
  "analyzer": "standard",
  "text": "尚硅谷电商项目"
}
## 使用ik_smart 分词器
POST _analyze
{
  "analyzer": "ik_smart",
  "text": "我是中国人"
}
## 使用ik_max_word 分词器
POST _analyze
{
  "analyzer": "ik_max_word",
  "text": "我是中国人"
}

测试结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8、自定义分ik分词库

默认的分词库给我们提供了基本的分词功能,但是对于某些网络热词和一些特殊词,时无法分词,这时候就需要我们自己去定义分词库
第一步:修改/usr/share/elasticsearch/plugins/ik/config/中的 IKAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict"></entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords"></entry>
<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict"><font color="red">http://192.168.128.130/fenci/myword.txt</font></entry>
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

http://192.168.128.130/fenci/myword.txt 这个时nginx的地址 内容如下
在这里插入图片描述
第二步:重启es容器
第三步:刷新kibana测试
在这里插入图片描述

9、java整合elasticsearch

最终选择:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html
在这里插入图片描述
第一步:添加依赖
注意:

boot的版本为:2.1.8.RELEASE
由于我们用的es的版本时7.4.2 与springboot为我们维护的版本不同所以需要改一下es的版本。

<elasticsearch.version>7.4.2</elasticsearch.version>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.2</version>
        </dependency>

完整配置:

<?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.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-search</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gulimall-search</name>
    <description>ElasticSearch检索服务</description>
    <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.4.2</elasticsearch.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<!--        导入ElasticSearch的操作工具类-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.2</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>

第二步:添加es的配置,创建一个RestHighLevelClient 到ioc容器中
192.168.56.10 这个地址是我本地的linux地址

@Configuration
public class GulimallElasticSearchConfig {

    /**
     * 用于安全校验的配置
     */
    public static final RequestOptions COMMON_OPTIONS;
    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
        // builder.addHeader("Authorization", "Bearer " + TOKEN);
        // builder.setHttpAsyncResponseConsumerFactory(
        //         new HttpAsyncResponseConsumerFactory
        //                 .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
        COMMON_OPTIONS = builder.build();
    }

    /**
     * 配置ElasticSearch地址,得到操作对象
     * @return
     */
    @Bean
    public RestHighLevelClient esRestClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("192.168.56.10", 9200, "http")));
        return  client;
    }

}

第三步:通过api文档调用https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

package com.atguigu.gulimall.search;

import com.alibaba.fastjson.JSON;
import com.atguigu.gulimall.search.config.GulimallElasticSearchConfig;
import lombok.Data;
import lombok.ToString;
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.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

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

@SpringBootTest
@RunWith(SpringRunner.class)
public class GulimallSearchApplicationTests {

	@Resource
	private RestHighLevelClient client;

	/**
	 * 复杂的聚合操作
	 * 查询处地址中带有mill,按照年龄聚合,并且请求这些年龄段的这些人的平局薪资
	 */
	@Test
	public void searchData() throws IOException{
		// 1. 创建检索请求
		SearchRequest searchRequest = new SearchRequest();
		// 2.指定索引
		searchRequest.indices("bank");
		// 3. 指定DSL ,检索条件
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchRequest.source(searchSourceBuilder);
			// 3.1 构造检索条件,所有的跟操作都可以找到
		searchSourceBuilder.query(QueryBuilders.matchQuery("address","mill"));
			// 3.2 按照年龄聚合
		TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
		searchSourceBuilder.aggregation(ageAgg);
		AvgAggregationBuilder banlceAvg = AggregationBuilders.avg("balanceAgg").field("balance");
		searchSourceBuilder.aggregation(banlceAvg);
		System.out.println("maruis------>" + searchSourceBuilder);
		// 4.执行检索
		SearchResponse searchResponse = client.search(searchRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
		System.out.println("maruis------>" + searchResponse.toString());
		// 5. 结果分析
		//Map map = JSON.parseObject(searchResponse.toString(), Map.class);
		SearchHits hits = searchResponse.getHits();
		SearchHit[] hitses = hits.getHits();
		for (SearchHit hit:hitses){
//			_index,_type,_id,_score
//			hit.getIndex();
//			hit.getType();
//			hit.getId();
//			hit.getScore();
			// _source
			String sourceAsString = hit.getSourceAsString();
			Accout accout = JSON.parseObject(sourceAsString,Accout.class);
			System.out.println("maruis------>" + accout.toString());
		}
		Aggregations aggregations = searchResponse.getAggregations();
//		for(Aggregation agg:aggregations.asList()){
//			System.out.println("maruis---当前聚合--->" + agg.getName());
//		}
		Terms ageAgg1 = aggregations.get("ageAgg");
		List<? extends Terms.Bucket> buckets = ageAgg1.getBuckets();
		for(Terms.Bucket bucket:buckets){
			String keyAsString = bucket.getKeyAsString();
			System.out.println("maruis----年龄:-->" +keyAsString+"    人数:"+bucket.getDocCount());
		}
		Avg balanceAgg = aggregations.get("balanceAgg");
		System.out.println("maruis----平均薪资:-->" + balanceAgg.getValue());
	}

	/**
	 * 验证es客户操作类是否可用
	 */
	@Test
	public void contextLoads() {
		System.out.println("maruis------>" + client);
	}

	/**
	 * 测试存储数据到es
	 */
	@Test
	public void indexData() throws IOException {
		IndexRequest indexRequest = new IndexRequest("users");
		// 唯一id
		indexRequest.id("1");
		//indexRequest.source("userName","张三","gender","男","age",18);
		User user = new User();
		user.setUserName("张三");
		user.setGender("男");
		user.setAge(23);
		String jsonString= JSON.toJSONString(user);
		indexRequest.source(jsonString, XContentType.JSON); // 要保存的数据
		// 执行保存操作
		IndexResponse index = client.index(indexRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);
		System.out.println("maruis------>" + index);
	}
	@Data
	class User{
		private String userName;
		private String gender;
		private Integer age;
	}
	@Data
	@ToString
	static class  Accout{
		private int account_number;
		private int balance;
		private String firstname;
		private String lastname;
		private int age;
		private String gender;
		private String address;
		private String employer;
		private String email;
		private String city;
		private String state;
	}

}

linux下安装wget和unzip工具

yum install wget -y
yum install unzip -y

nigix安装

 随便启动一个 nginx 实例,只是为了复制出配置
 docker run -p 80:80 --name nginx -d nginx:1.10
 将容器内的配置文件拷贝到当前目录:docker container cp nginx:/etc/nginx . 别忘了后面的点
 修改文件名称:mv nginx conf 把这个 conf 移动到/mydata/nginx 下
 终止原容器:docker stop nginx
 执行命令删除原容器:docker rm $ContainerId
 创建新的 nginx;执行以下命令
docker run -p 80:80 --name nginx
-v /mydata/nginx/html:/usr/share/nginx/html
-v /mydata/nginx/logs:/var/log/nginx
-v /mydata/nginx/conf:/etc/nginx
-d nginx:1.10
 给 nginx 的 html 下面放的所有资源可以直接访问;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值