入坑实战、首先还是要先认识框架的前言
Elasticsearch官网
一、开源搜索引擎排名第一,Elasticsearch是如何做到的
帮你们在度娘筛选了:上车了解前言
二、ElasticSearch、IK分词器、Head Master可视化安装-----Windows
ElasticSearch安装运行前提条件:配置好Jdk
Head-Master运行前提条件:node
(重点: 一定要用管理员运行CMD)
- ElasticSearch 下载:https://www.elastic.co/cn/downloads/elasticsearch
- IK分词器 下载:下载:https://github.com/medcl/elasticsearch-analysis-ik/releases 安装配置:https://blog.csdn.net/wsms007/article/details/86569285
- Head Master 下载:https://github.com/mobz/elasticsearch-head 安装部署:https://blog.csdn.net/qq_26710805/article/details/78197922
- 也可以在游览器 - ->更多工具 - ->扩展程序 - ->下载ElasticSearch Head程序 - - >启动本地下载ElasticSearch Head - ->连接ElasticSearch Head程序
三、入门Elasticsearch搜索引擎的实战
- 导入或下载依赖包
- 配置连接池工具类
package org.scbit.wuzi.util.es;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.elasticsearch.client.RestHighLevelClient;
/**
* ElasticSearch 连接池工具类
*
* @author 00000
*
*/
public class ElasticSearchPoolUtil {
// 对象池配置类,不写也可以,采用默认配置
private static GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
// 采用默认配置maxTotal是8,池中有8个client
static {
poolConfig.setMaxTotal(8);
}
// 要池化的对象的工厂类,这个是我们要实现的类
private static EsClientPoolFactory esClientPoolFactory = new EsClientPoolFactory();
// 利用对象工厂类和配置类生成对象池
private static GenericObjectPool<RestHighLevelClient> clientPool = new GenericObjectPool<>(esClientPoolFactory,poolConfig);
/**
* 获得对象
*
* @return
* @throws Exception
*/
public static RestHighLevelClient getClient() throws Exception {
// 从池中取一个对象
RestHighLevelClient client = clientPool.borrowObject();
return client;
}
/**
* 归还对象
*
* @param client
*/
public static void returnClient(RestHighLevelClient client) {
// 使用完毕之后,归还对象
clientPool.returnObject(client);
}
}
- 连接池工厂对象类
package org.scbit.wuzi.util.es;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
/**
* EliasticSearch连接池工厂对象
* @author 00000
*
*/
public class EsClientPoolFactory implements PooledObjectFactory<RestHighLevelClient>{
@Override
public void activateObject(PooledObject<RestHighLevelClient> arg0) throws Exception {
System.out.println("activateObject");
}
/**
* 销毁对象
*/
@Override
public void destroyObject(PooledObject<RestHighLevelClient> pooledObject) throws Exception {
RestHighLevelClient highLevelClient = pooledObject.getObject();
highLevelClient.close();
}
/**
* 生产对象
*/
// @SuppressWarnings({ "resource" })
@Override
public PooledObject<RestHighLevelClient> makeObject() throws Exception {
// Settings settings = Settings.builder().put("cluster.name","elasticsearch").build();
RestHighLevelClient client = null;
try {
client = new RestHighLevelClient(RestClient.builder(
new HttpHost("127.0.0.1", 8080, "http")));
} catch (Exception e) {
e.printStackTrace();
}
return new DefaultPooledObject<RestHighLevelClient>(client);
}
@Override
public void passivateObject(PooledObject<RestHighLevelClient> arg0) throws Exception {
System.out.println("passivateObject");
}
@Override
public boolean validateObject(PooledObject<RestHighLevelClient> arg0) {
return true;
}
}
- 操作es方法类
package org.scbit.wuzi.util.es;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
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.support.WriteRequest;
import org.elasticsearch.action.support.replication.ReplicationResponse;
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.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.DocWriteResponse;
/**
* AccountAction
* @author ding
* @version 2021\5
* @since JDK1.8
*/
public class ElasticClient {
private static final String INDEX_KEY = "index";
private static final String TYPE_KEY = "type";
private static final String INDEX = "spider";
private static final String TYPE = "doc";
private static final String TIMESTAMP = "timestamp";
//操作客户端对象
protected static RestHighLevelClient client=null;
static {
ElasticSearchPoolUtil elasticSearchPoolUtil=new ElasticSearchPoolUtil();
try {
client = elasticSearchPoolUtil.getClient();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 创建索引
public void createIndex(String indexName) throws IOException {
if (checkIndexExists(indexName)) {
return;
}
CreateIndexRequest request = new CreateIndexRequest(indexName);
request.mapping(TYPE, generateBuilder());
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
// 指示是否所有节点都已确认请求
boolean acknowledged = response.isAcknowledged();
// 指示是否在超时之前为索引中的每个分片启动了必需的分片副本数
boolean shardsAcknowledged = response.isShardsAcknowledged();
if (acknowledged || shardsAcknowledged) {
}
}
/**
* 判断索引是否存在
* @param indexName
* @return
* @throws IOException
*/
public boolean checkIndexExists(String indexName) {
GetIndexRequest request = new GetIndexRequest().indices(indexName);
try {
return client.indices().exists(request, RequestOptions.DEFAULT);
} catch (IOException e) {
}
return false;
}
private XContentBuilder generateBuilder() throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
builder.startObject("properties");
builder.startObject("message");
builder.field("type", "text");
// 为message字段,设置分词器为 ik_smart(最粗粒度)
builder.field("analyzer", "ik_smart");
builder.endObject();
builder.startObject(TIMESTAMP);
builder.field("type", "date");
// 设置 日志时间的格式为 毫秒数的long类型
builder.field("format", "epoch_millis");
builder.endObject();
builder.endObject();
builder.endObject();
return builder;
}
/**
* 增加文档
* @param indexName
* @param typeName
* @param id
* @param jsonStr
*/
public void addDocByJson(String indexName, String typeName, String id, String jsonString) throws IOException{
if (!checkIndexExists(indexName)) {
createIndex(indexName);
}
IndexRequest request = new IndexRequest(indexName, typeName, id).source(jsonString, XContentType.JSON);
// request的opType默认是INDEX(传入相同id会覆盖原document,CREATE则会将旧的删除)
// request.opType(DocWriteRequest.OpType.CREATE)
IndexResponse response = null;
try {
response = client.index(request, RequestOptions.DEFAULT);
String index = response.getIndex();
String type = response.getType();
String documentId = response.getId();
if (response.getResult() == DocWriteResponse.Result.CREATED) {
} else if (response.getResult() == DocWriteResponse.Result.UPDATED) {
}
// 分片处理信息
ReplicationResponse.ShardInfo shardInfo = response.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
}
// 如果有分片副本失败,可以获得失败原因信息
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();
}
}
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
}
}
}
/**
* 删除文档
* @param index
* @param type
* @param id
* @throws IOException
*/
public void deleteDocument(String index, String type, String id) throws IOException {
DeleteRequest request = new DeleteRequest(index, type, id);
DeleteResponse response = null;
try {
response = client.delete(request, RequestOptions.DEFAULT);
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.CONFLICT) {
}
}
if (Objects.nonNull(response)) {
if (response.getResult() == DocWriteResponse.Result.NOT_FOUND) {
}
ReplicationResponse.ShardInfo shardInfo = response.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();
}
}
}
}
/**
* 通过一个JSON字符串更新文档(如果该文档不存在,则根据参数创建这个文档)
* @param index
* @param type
* @param id
* @param jsonString
* @throws IOException
*/
public void updateDocByJson(String index, String type, String id, String jsonString) throws IOException {
if (!checkIndexExists(index)) {
createIndex(index);
}
UpdateRequest request = new UpdateRequest(index, type, id);
request.doc(jsonString, XContentType.JSON);
// 如果要更新的文档不存在,则根据传入的参数新建一个文档
request.docAsUpsert(true);
try {
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
String indexName = response.getIndex();
String typeName = response.getType();
String documentId = response.getId();
if (response.getResult() == DocWriteResponse.Result.CREATED) {
} else if (response.getResult() == DocWriteResponse.Result.UPDATED) {
} else if (response.getResult() == DocWriteResponse.Result.DELETED) {
} else if (response.getResult() == DocWriteResponse.Result.NOOP) {
}
ReplicationResponse.ShardInfo shardInfo = response.getShardInfo();
if (shardInfo.getTotal() != shardInfo.getSuccessful()) {
}
if (shardInfo.getFailed() > 0) {
for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
String reason = failure.reason();
}
}
} catch (ElasticsearchException e) {
if (e.status() == RestStatus.NOT_FOUND) {
} else if (e.status() == RestStatus.CONFLICT) {
}
}
}
/**
* 批量增加文档
* @param params
* @throws IOException
*/
public void bulkAdd(List<Map<String, String>> params) throws IOException {
BulkRequest bulkRequest = new BulkRequest();
for (Map<String, String> dataMap : params) {
String index = dataMap.getOrDefault(INDEX_KEY, INDEX);
String type = dataMap.getOrDefault(TYPE_KEY, TYPE);
String id = dataMap.get("id");
String jsonString = dataMap.get("json");
if (StringUtils.isNotBlank(id)) {
IndexRequest request = new IndexRequest(index, type, id).source(jsonString, XContentType.JSON);
bulkRequest.add(request);
}
}
// 超时时间(2分钟)
bulkRequest.timeout(TimeValue.timeValueMinutes(2L));
// 刷新策略
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
if (bulkRequest.numberOfActions() == 0) {
return;
}
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
// 全部操作成功
if (!bulkResponse.hasFailures()) {
} else {
for (BulkItemResponse bulkItemResponse : bulkResponse) {
if (bulkItemResponse.isFailed()) {
BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
} else {
}
}
}
}
/**
* 批量更新文档
* @param params
* @throws IOException
*/
public void bulkUpdate(List<Map<String, String>> params) throws IOException {
BulkRequest bulkRequest = new BulkRequest();
for (Map<String, String> dataMap : params) {
String index = dataMap.getOrDefault(INDEX_KEY, INDEX);
String type = dataMap.getOrDefault(TYPE_KEY, TYPE);
String id = dataMap.get("id");
String jsonString = dataMap.get("json");
if (StringUtils.isNotBlank(id) ) {
UpdateRequest request = new UpdateRequest(index, type, id).doc(jsonString, XContentType.JSON);
request.docAsUpsert(true);
bulkRequest.add(request);
}
}
if (bulkRequest.numberOfActions() == 0) {
return;
}
bulkRequest.timeout(TimeValue.timeValueMinutes(2L));
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
if (!bulkResponse.hasFailures()) {
} else {
for (BulkItemResponse bulkItemResponse : bulkResponse) {
if (bulkItemResponse.isFailed()) {
BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
} else {
}
}
}
}
/**
* 批量删除文档
* @param params
* @throws IOException
*/
public void bulkDelete(List<Map<String, String>> params) throws IOException {
BulkRequest bulkRequest = new BulkRequest();
for (Map<String, String> dataMap : params) {
String index = dataMap.getOrDefault(INDEX_KEY, INDEX);
String type = dataMap.getOrDefault(TYPE_KEY, TYPE);
String id = dataMap.get("id");
if (StringUtils.isNotBlank(id)){
DeleteRequest request = new DeleteRequest(index, type, id);
bulkRequest.add(request);
}
}
if (bulkRequest.numberOfActions() == 0) {
return;
}
bulkRequest.timeout(TimeValue.timeValueMinutes(2L));
bulkRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
if (!bulkResponse.hasFailures()) {
} else {
for (BulkItemResponse bulkItemResponse : bulkResponse) {
if (bulkItemResponse.isFailed()) {
BulkItemResponse.Failure failure = bulkItemResponse.getFailure();
} else {
}
}
}
}
}
修改和新增可以一起使用,因为新增会覆盖,所以只需要做新增就行了
实例:
添加、更新
//设置转json过滤器,过滤掉值为null值的情况
JsonConfig cfg = new JsonConfig();
cfg.setJsonPropertyFilter(new PropertyFilter() {
@Override
public boolean apply(Object arg0, String arg1, Object arg2) {
// TODO Auto-generated method stub
return arg2==null;
}
});
String date = JSONObject.fromObject(对象信息,cfg).toString();
elasticClient.addDocByJson("索引名称", "索引名称",ID.toString(),date);
删除
//先删除es该条记录
elasticClient.deleteDocument("索引名称", "索引名称", ID.toString());在这里插入代码片
查询(模糊,集合排序,排序)
//从连接池中获取es客户端操作对象
private ElasticSearchPoolUtil elasticSearchPoolUtil= null;
//查询订单条件查询
public SearchResponse EsFindOrder(T t,int startpage,int size) throws Exception {
RestHighLevelClient restHighLevelClient = elasticSearchPoolUtil.getClient();
//查询订单索引
SearchRequest searchRequest = new SearchRequest("registered_order");
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchRequest.setCcsMinimizeRoundtrips(false);
searchRequest.setCcsMinimizeRoundtrips(false);
BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery();
// TODO 注意这些都是查询实例需要根据实际去修改查询条件
//订单ID
if(null != t.getOrderIds() && t.getOrderIds().size() > 0) {
List<Long> orderIds = t.getOrderIds();
boolQueryBuilder.filter(QueryBuilders.termsQuery("order_id", orderIds));
}
//发票编号不为空,模糊查询发票编号
if(!StringUtil.isEmpty(t.getOrderTrackingNum())) {
String nvoiceNum=t.getOrderTrackingNum();
WildcardQueryBuilder order_codeQuery = QueryBuilders.wildcardQuery("order_tracking_num","*"+nvoiceNum+"*");
boolQueryBuilder.filter(order_codeQuery);
}
//品牌名精确查询
if(!StringUtil.isEmpty(t.getBrandName())) {
String brandname=t.getBrandName();
TermQueryBuilder brand_nameQuery = QueryBuilders.termQuery("brand_name.keyword",brandname);
boolQueryBuilder.filter(brand_nameQuery);
}
//产品货号模糊查询 中英文分类
if(!StringUtil.isEmpty(t.getProductCode())) {
if (orderVO.getProductCode().matches("^[a-zA-Z0-9]*")) {
String productcode=t.getProductCode();
WildcardQueryBuilder order_codeQuery = QueryBuilders.wildcardQuery("product_code.keyword","*"+productcode+"*");
boolQueryBuilder.filter(order_codeQuery);
}else {
String productcode=t.getProductCode();
MatchPhraseQueryBuilder order_codeQuery = QueryBuilders.matchPhraseQuery("product_code.keyword",productcode);
boolQueryBuilder.filter(order_codeQuery);
}
}
//时间范围查询 分别为领用开始时间和领用结束时间
Date UseTimeStart = t.getOrderUseTimeStart();
Date UseTimeEnd = t.getOrderUseTimeEnd();
//两个时间范围都不为空
if(UseTimeStart!=null ) {
//范围查询构建
RangeQueryBuilder rangeStarttime = QueryBuilders.rangeQuery("order_use_time").gte(UseTimeStart);
boolQueryBuilder.filter(rangeStarttime);
}
if(UseTimeEnd!=null) {
RangeQueryBuilder rangeStarttime = QueryBuilders.rangeQuery("order_use_time").lte(UseTimeEnd);
boolQueryBuilder.filter(rangeStarttime);
}
//查询order_cancel_type为null或者为2的数据,在总的数据结果之后进行二次过滤
if(!StringUtil.isEmpty(t.getOrderCancelType())) {
TermQueryBuilder t= QueryBuilders.termQuery("order_cancel_type.keyword", "2");
BoolQueryBuilder b= QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("order_cancel_type.keyword"));
BoolQueryBuilder boolQueryBuilder2= QueryBuilders.boolQuery();
boolQueryBuilder2.should(b).should(t);
boolQueryBuilder.filter(boolQueryBuilder2);
}
//默认排序为下单时间倒序
//字段值为text需要加order_xx.keyword
searchSourceBuilder.sort("order_date", SortOrder.DESC);
// searchSourceBuilder.sort("order_date", SortOrder.ASC);
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.size(size);
searchSourceBuilder.from(startpage);
searchSourceBuilder.trackTotalHits(true);//设置为true,默认false,ES数据统计和最大值为10000
searchRequest.source(searchSourceBuilder);//拼装好条件放进去
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
elasticSearchPoolUtil.returnClient(restHighLevelClient);
return searchResponse;
}
返回数据转换输出对象
//将searchResponse响应对象转换为页面标准输出对象
public List esOrderList(SearchResponse searchResponse) throws Exception {
//获取命中的对象
SearchHits hits= searchResponse.getHits();
//订单集合对象
List<T> ts= new ArrayList<T>();
for(SearchHit serHit:hits) {
T t=new T();
Map<String, Object> sourceAsMap=serHit.getSourceAsMap();
//添加用户信息
t.setUserId((String)sourceAsMap.get("order_user_id"));
t.setUserName((String)sourceAsMap.get("order_user_name"));
t.setUser(orderUser);
//课题组相关信息
t.setIssueGroupLeader((String)sourceAsMap.get("issue_group_leader"));
t.setIssueGroupName((String)sourceAsMap.get("issue_group_name"));
//订单接收时间
t.setOrderAcceptDate((String)sourceAsMap.get("order_accept_date"));
ts.add(t);
}
return ts;
}