一、安裝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);
}
}