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环境正常
下载

根据自己的操作系统下载对应版本的es
下载地址:https://www.elastic.co/cn/downloads/elasticsearch

相关目录说明
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文件夹下的所有目录的所有权限迭代给esuser用户
chgrp -R esuser ./es chown -R esuser ./es chmod 777 es 切换到esuser用户启动 nohup ./bin/elasticsearch & 或 ./bin/elasticsearch
启动成功

测试

三、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

连接访问

查看或新增索引

查看索引数据

四、kibana安装、可操作界面(选用)
官网:https://www.elastic.co/cn/kibana

声明:kibana版本要和Es版本一致。
下载地址:https://www.elastic.co/cn/downloads/kibana

解压直接启动

连接访问

五、Elaticsearch 使用介绍
elasticsearch是面向文档 关系行数据库和elasticsearch客观的对比
| Relational DB | Elasticsearch |
|---|---|
| 数据库(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;
}
1888





