一、安装ES
下载ES包,去官网下载页可以:
#大约280M
链接:https://pan.baidu.com/s/1LaWlIwrI7UxVEdytoD1JWw
提取码:6p0j
压缩包上传到/usr/local目录下
tar -xzvf elasticsearch-7.5.0-linux-x86_64.tar.gz
adduser es
#赋予文件夹权限
chown -R es /usr/local/elasticsearch-7.5.0/
#切换用户
su es
/usr/local/elasticsearch-7.5.0/bin/elasticsearch -d #-d 在后台以守护进程模式运行
#校验运行情况,出现下图则代表启动成功:
netstat -lntp
curl 'http://localhost:9200/?pretty'
二、简单配置ES
#修改配置文件
vi /usr/local/elasticsearch-7.5.0/config/elasticsearch.yml
# Use a descriptive name for your cluster:
# 起的名字
cluster.name: big-data
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
# 节点名字
node.name: node-1
#
#
# Set the bind address to a specific IP (IPv4 or IPv6):
# 当前主节点的host
network.host: 123.57.133.22
#当前局域网节点 单机es则配置127.0.0.1
transport.host: 127.0.0.1
#网络限制ip 当前配置不做任何限制,任何ip都能访问当前es
http.host: 0.0.0.0
#
# Set a custom port for HTTP:
# 端口,默认也为9200
http.port: 9200
三、一般报错处理
1、max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
每个进程最大同时打开文件数太小,可通过下面2个命令查看当前数量
ulimit -Hn
ulimit -Sn
修改/etc/security/limits.conf文件,增加配置,用户退出后重新登录生效
* soft nofile 65536
* hard nofile 65536
2、max number of threads [3818] for user [es] is too low, increase to at least [4096]
问题同上,最大线程个数太低。修改配置文件/etc/security/limits.conf(和问题1是一个文件),增加配置
* soft nproc 4096
* hard nproc 4096
#可通过命令查看
ulimit -Hu
ulimit -Su
3、max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
修改/etc/sysctl.conf文件,增加配置vm.max_map_count=262144
vi /etc/sysctl.conf
sysctl -p #执行命令sysctl -p生效
4、Exception in thread “main” java.nio.file.AccessDeniedException: /usr/local/elasticsearch/elasticsearch-6.2.2-1/config/jvm.options
elasticsearch用户没有该文件夹的权限,执行命令
chown -R es:es /usr/local/elasticsearch/
四、springBoot集成ES
1. 引入maven
<!--es依赖 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.5.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.5.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.5.0</version>
<scope>compile</scope>
</dependency>
2.配置application.properties或yml文件
elasticsearch.user: #用户 未设置则空
elasticsearch.password: #密码 未设置则空
elasticsearch.host: 123.57.xx.xx:9200 #ip和端口号
3.简单新增操作
/**
* 添加
* @return
*/
@RequestMapping(value="add",method = RequestMethod.POST)
public void add( ){
String index = "my_index";
try {
for(int i=0;i<20;i++) {
XContentBuilder builder = XContentFactory.jsonBuilder()
.startObject()
.field("id", i+"")
.field("content", "内容"+i)
.field("age",(20+i)+"")
.endObject();
String id = ESUtil.addData(builder, index, i+"");
logger.info("插入一条数据,id为{}",i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
4.简单删除操作
/**
* 删除
* @return
*/
@RequestMapping(value="delete",method = RequestMethod.POST)
@ResponseBody
public String delete(@RequestParam String id){
String index = "my_index";
//根据id删除
String status = ESUtil.deleteById(index, id);
//打印查询结果
return "success";
}
5.简单修改操作
/**
* 更新
* @return
*/
@RequestMapping(value="update",method = RequestMethod.POST)
public String update(@RequestParam String id)throws Exception{
String index = "my_index";
XContentBuilder builder =XContentFactory.jsonBuilder()
.startObject()
.field("id",id)
.field("content","这是内容"+id)
.field("age",id).endObject();
String responseId = ESUtil.updateData(builder, index, id);
logger.info("打印更新的id"+responseId);
//打印查询结果
return responseId;
}
6.简单查询操作
/**
* 分页+条件查询
* @return
*/
@RequestMapping(value="get",method = RequestMethod.POST)
public void get( ){
String index = "my_index";
//分页+条件查询
BoolQueryBuilder builder = QueryBuilders.boolQuery();
builder.must(QueryBuilders.matchQuery("content","内容2"));
SearchSourceBuilder sourceBuilder =new SearchSourceBuilder();
List<Map<String, Object>> list = ESUtil.SearchDataPage(index, 1, 20, sourceBuilder, builder);
//打印查询结果
System.out.println(list);
}
7.上面代码用到的工具类
ESUtil
package com.example.util;
import com.example.pojo.EsEntity;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
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.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Component
public class ESUtil {
private static final Logger log = LoggerFactory.getLogger(ESUtil.class);
@Qualifier("highLevelClient")
@Autowired
private RestHighLevelClient rhlClient;
private static RestHighLevelClient client;
/**
* spring容器初始化的时候执行该方法
*/
@PostConstruct
public void init() {
client = this.rhlClient;
}
/**
* 添加数据
*
* @param content 数据内容
* @param index 索引
* @param id id
*/
public static String addData(XContentBuilder content, String index, String id) {
String Id = null;
try {
IndexRequest request = new IndexRequest(index).id(id).source(content);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
Id = response.getId();
log.info("索引:{},数据添加,返回码:{},id:{}", index, response.status().getStatus(), Id);
} catch (IOException e) {
log.error("添加数据失败,index:{},id:{}", index, id);
}
return Id;
}
/**
* 修改数据
*
* @param content 修改内容
* @param index 索引
* @param id id
*/
public static String updateData(XContentBuilder content, String index, String id) {
String Id = null;
try {
UpdateRequest request = new UpdateRequest(index, id).doc(content);
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
Id = response.getId();
log.info("数据更新,返回码:{},id:{}", response.status().getStatus(), Id);
} catch (IOException e) {
log.error("数据更新失败,index:{},id:{}", index, id);
}
return Id;
}
/**
* 批量插入数据
*
* @param index 索引
* @param list 批量增加的数据
*/
public static String insertBatch(String index, List<EsEntity> list) {
String state = null;
BulkRequest request = new BulkRequest();
list.forEach(item -> request.add(new IndexRequest(index)
.id(item.getId()).source(JsonUtils.toJson(item.getData()), XContentType.JSON)));
try {
BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
int status = bulk.status().getStatus();
state = Integer.toString(status);
log.info("索引:{},批量插入{}条数据成功!", index, list.size());
} catch (IOException e) {
log.error("索引:{},批量插入数据失败", index);
}
return state;
}
/**
* 根据条件删除数据
*
* @param index 索引
* @param builder 删除条件
*/
public static void deleteByQuery(String index, QueryBuilder builder) {
DeleteByQueryRequest request = new DeleteByQueryRequest(index);
request.setQuery(builder);
//设置此次删除的最大条数
request.setBatchSize(1000);
try {
client.deleteByQuery(request, RequestOptions.DEFAULT);
} catch (IOException e) {
log.error("根据条件删除数据失败,index:{}", index);
}
}
/**
* 根据id删除数据
*
* @param index 索引
* @param id id
*/
public static String deleteById(String index, String id) {
String state = null;
DeleteRequest request = new DeleteRequest(index, id);
try {
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
int status = response.status().getStatus();
state = Integer.toString(status);
log.info("索引:{},根据id{}删除数据:{}", index, id, JsonUtils.toJson(response));
} catch (IOException e) {
log.error("根据id删除数据失败,index:{},id:{}", index, id);
}
return state;
}
/**
* 根据条件查询数据
*
* @param index 索引
* @param startPage 开始页
* @param pageSize 每页条数
* @param sourceBuilder 查询返回条件
* @param queryBuilder 查询条件
*/
public static List<Map<String, Object>> SearchDataPage(String index, int startPage, int pageSize,
SearchSourceBuilder sourceBuilder, QueryBuilder queryBuilder) {
SearchRequest request = new SearchRequest(index);
//设置超时时间
sourceBuilder.timeout(new TimeValue(120, TimeUnit.SECONDS));
//设置是否按匹配度排序
sourceBuilder.explain(true);
//加载查询条件
sourceBuilder.query(queryBuilder);
//设置分页
sourceBuilder.from((startPage - 1) * pageSize).size(pageSize);
log.info("查询返回条件:" + sourceBuilder.toString());
request.source(sourceBuilder);
try {
SearchResponse searchResponse = client.search(request, RequestOptions.DEFAULT);
long totalHits = searchResponse.getHits().getTotalHits().value;
log.info("共查出{}条记录", totalHits);
RestStatus status = searchResponse.status();
if (status.getStatus() == 200) {
List<Map<String, Object>> sourceList = new ArrayList<>();
for (SearchHit searchHit : searchResponse.getHits().getHits()) {
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
sourceList.add(sourceAsMap);
}
return sourceList;
}
} catch (IOException e) {
log.error("条件查询索引{}时出错", index);
}
return null;
}
}
用到的EsEntity
package com.example.pojo;
public class EsEntity {
private String id;
private Object data;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
用到的JsonUtils
package com.example.util;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author xiaolang
* @version 1.0.0
*/
public class JsonUtils {
private static Logger logger = LoggerFactory.getLogger(JsonUtils.class);
private static final ObjectMapper objectMapper;
static {
objectMapper = new ObjectMapper();
//去掉默认的时间戳格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//设置为中国上海时区
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
// objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
//空值不序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//反序列化时,属性不存在的兼容处理
objectMapper.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//序列化时,日期的统一格式
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//单引号处理
objectMapper.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
}
public static <T> T toObject(String json, Class<T> clazz) {
try {
return objectMapper.readValue(json, clazz);
} catch (JsonParseException e) {
logger.error(e.getMessage(), e);
} catch (JsonMappingException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}
public static <T> String toJson(T entity) {
try {
return objectMapper.writeValueAsString(entity);
} catch (JsonGenerationException e) {
logger.error(e.getMessage(), e);
} catch (JsonMappingException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}
public static <T> T toCollection(String json, TypeReference<T> typeReference) {
try {
return objectMapper.readValue(json, typeReference);
} catch (JsonParseException e) {
logger.error(e.getMessage(), e);
} catch (JsonMappingException e) {
logger.error(e.getMessage(), e);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}
/**
* json string convert to map
*/
public static <T> Map<String, Object> json2map(String jsonStr)
throws Exception {
return objectMapper.readValue(jsonStr, Map.class);
}
/**
* json string convert to map with javaBean
*/
public static <T> Map<String, T> json2map(String jsonStr, Class<T> clazz)
throws Exception {
Map<String, Map<String, Object>> map = objectMapper.readValue(jsonStr,
new TypeReference<Map<String, T>>() {
});
Map<String, T> result = new HashMap<String, T>();
for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
}
return result;
}
/**
* json array string convert to list with javaBean
*/
public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz)
throws Exception {
List<Map<String, Object>> list = objectMapper.readValue(jsonArrayStr,
new TypeReference<List<T>>() {
});
List<T> result = new ArrayList<T>();
for (Map<String, Object> map : list) {
result.add(map2pojo(map, clazz));
}
return result;
}
/**
* map convert to javaBean
*/
public static <T> T map2pojo(Map map, Class<T> clazz) {
return objectMapper.convertValue(map, clazz);
}
}