Compatibility
The Java High Level REST Client requires Java 1.8 and depends on the Elasticsearch core project. The client version is the same as the Elasticsearch version that the client was developed for. It accepts the same request arguments as the
TransportClient
and returns the same response objects. See the
Migration Guide
if you need to migrate an application from
TransportClient
to the new REST client.
The High Level Client is guaranteed to be able to communicate with any Elasticsearch node running on the same major version and greater or equal minor version. It doesn’t need to be in the same minor version as the Elasticsearch nodes it communicates with, as it is forward compatible meaning that it supports communicating with later versions of Elasticsearch than the one it was developed for.
The 6.0 client is able to communicate with any 6.x Elasticsearch node, while the 6.1 client is for sure able to communicate with 6.1, 6.2 and any later 6.x version, but there may be incompatibility issues when communicating with a previous Elasticsearch node version, for instance between 6.1 and 6.0, in case the 6.1 client supports new request body fields for some APIs that are not known by the 6.0 node(s).
It is recommended to upgrade the High Level Client when upgrading the Elasticsearch cluster to a new major version, as REST API breaking changes may cause unexpected results depending on the node that is hit by the request, and newly added APIs will only be supported by the newer version of the client. The client should always be updated last, once all of the nodes in the cluster have been upgraded to the new major version.
Test Case
ES:5.2.2
POM
:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.2.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>6.2.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.2.4</version>
</dependency>
Initialization
A
RestHighLevelClient
instance needs a
REST low-level client builder
to be built as follows:
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
The high-level client will internally create the low-level client used to perform requests based on the provided builder. That low-level client maintains a pool of connections and starts some threads so you should close the high-level client when you are well and truly done with it and it will in turn close the internal low-level client to free those resources. This can be done through the
close
:
client.close();
In the rest of this documentation about the Java High Level Client, the
RestHighLevelClient
instance will be referenced as
client
.
Supported APIs
import
com.fasterxml.jackson.core.type.TypeReference;
import
com.fasterxml.jackson.databind.JsonNode;
import
com.ftofs.esclient.common.ESAnnotation.IndexAnnotation;
import
com.ftofs.esclient.common.JsonHelper;
import
com.ftofs.esclient.vo.CommentResultVo;
import
com.ftofs.esclient.vo.ImResultVo;
import
com.ftofs.esclient.vo.PostResultVo;
import
com.ftofs.esclient.vo.SearchCommentResultVo;
import
com.ftofs.esclient.vo.SearchImResultVo;
import
com.ftofs.esclient.vo.SearchPostResultVo;
import
org.apache.http.HttpEntity;
import
org.apache.http.HttpHost;
import
org.apache.http.entity.StringEntity;
import
org.apache.http.util.EntityUtils;
import
org.elasticsearch.ElasticsearchException;
import
org.elasticsearch.action.ActionListener;
import
org.elasticsearch.action.DocWriteResponse;
import
org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import
org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import
org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import
org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
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.IndicesOptions;
import
org.elasticsearch.action.support.WriteRequest;
import
org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
import
org.elasticsearch.client.Response;
import
org.elasticsearch.client.RestClient;
import
org.elasticsearch.client.RestHighLevelClient;
import
org.elasticsearch.common.Strings;
import
org.elasticsearch.common.settings.Settings;
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.slf4j.Logger;
import
org.slf4j.LoggerFactory;
import
org.springframework.beans.factory.annotation.Value;
import
org.springframework.stereotype.Component;
import
javax.annotation.PostConstruct;
import
javax.annotation.PreDestroy;
import
java.io.IOException;
import
java.util.ArrayList;
import
java.util.HashMap;
import
java.util.List;
@Component
public
class
ESRestService {
private
RestHighLevelClient client =
null
;
private
RestClient lowClient =
null
;
protected
final
Logger logger =
LoggerFactory.getLogger(getClass());
@Value(
"${esHost}"
)
private
String esHost;
@Value(
"${esPort}"
)
private
int
esPort;
@Value(
"${esScheme}"
)
private
String esScheme;
@Value(
"${esIndexImMessage}"
)
private
String esIndexImMessage;
@Value(
"${esTypeImMessage}"
)
private
String esTypeImMessage;
@Value(
"${esIndexWantPost}"
)
private
String esIndexWantPost;
@Value(
"${esTypeWantPost}"
)
private
String esTypeWantPost;
@Value(
"${esIndexWantComment}"
)
private
String esIndexWantComment;
@Value(
"${esTypeWantComment}"
)
private
String esTypeWantComment;
public
void
imReindexRange(List<ImResultVo>
imResultVoList) {
bulkInsert(esIndexImMessage, esTypeImMessage, imResultVoList);
public
void
postReindexRange(List<PostResultVo>
postResultVoList) {
bulkInsert(esIndexWantPost, esTypeWantPost, postResultVoList);
public
void
commentReindexRange(List<CommentResultVo>
commentResultVoList) {
bulkInsert(esIndexWantComment, esTypeWantComment, commentResultVoList);
public
SearchCommentResultVo wantCommentSearch(HashMap<String, Object>
queryMap) {
StringBuilder entity
=
new
StringBuilder();
entity.append(
"{"
);
entity.append(getWantCommentQueryPage(queryMap));
entity.append(
"\"query\" : {\"bool\" : { \"must\" : ["
);
entity.append(getWantCommentQuerySearch(queryMap));
entity.append(getWantCommentQueryRange(queryMap));
entity.append(
"]"
);
entity.append(getWantCommentQueryFilter(queryMap));
entity.append(
"}}"
);
entity.append(getWantCommentQueryString(queryMap));
entity.append(getWantCommentQuerySort(queryMap));
entity.append(getWantCommentQueryAggs());
entity.append(
"}"
);
logger.info(entity.toString());
HttpEntity httpEntity
=
new
StringEntity(entity.toString(), "utf-8"
);
HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory
=
new
HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024
);
SearchCommentResultVo searchCommentResultVo
=
new
SearchCommentResultVo();
try
{
Response response
=
lowClient.performRequest(
"GET", "/" + esIndexWantComment + "/_search",
new
HashMap<>
(), httpEntity, consumerFactory);
String responseBody
=
EntityUtils.toString(response.getEntity());
JsonNode jsonNode
=
JsonHelper.toJsonNode(responseBody);
logger.info(responseBody);
searchCommentResultVo.setTotal(jsonNode.get(
"hits").get("total"
).asInt());
searchCommentResultVo.setResultList(getSearchCommentResultVoList(jsonNode.get(
"hits").get("hits"
)));
}
catch
(IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
return
searchCommentResultVo;
public
SearchPostResultVo wantPostSearch(HashMap<String, Object>
queryMap) {
StringBuilder entity
=
new
StringBuilder();
entity.append(
"{"
);
entity.append(getWantPostQueryPage(queryMap));
entity.append(
"\"query\" : {\"bool\" : { \"must\" : ["
);
entity.append(getWantPostQuerySearch(queryMap));
entity.append(getWantPostQueryFilterPhrase(queryMap));
entity.append(getWantPostQueryRange(queryMap));
entity.append(
"]"
);
entity.append(getWantPostQueryFilter(queryMap));
entity.append(
"}}"
);
entity.append(getWantPostQueryString(queryMap));
entity.append(getWantPostQuerySort(queryMap));
entity.append(getWantPostQueryAggs());
entity.append(getWantPostQuerySource(queryMap));
entity.append(
"}"
);
logger.info(entity.toString());
HttpEntity httpEntity
=
new
StringEntity(entity.toString(), "utf-8"
);
HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory
=
new
HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024
);
SearchPostResultVo searchPostResultVo
=
new
SearchPostResultVo();
try
{
Response response
=
lowClient.performRequest(
"GET", "/" + esIndexWantPost + "/_search",
new
HashMap<>
(), httpEntity, consumerFactory);
String responseBody
=
EntityUtils.toString(response.getEntity());
JsonNode jsonNode
=
JsonHelper.toJsonNode(responseBody);
logger.info(responseBody);
searchPostResultVo.setTotal(jsonNode.get(
"hits").get("total"
).asInt());
searchPostResultVo.setResultList(getSearchPostResultVoList(jsonNode.get(
"hits").get("hits"
)));
}
catch
(IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
return
searchPostResultVo;
public
SearchImResultVo imMessageSearch(HashMap<String, Object>
queryMap) {
//
es <5.4.0 不支持高級查詢語法
//
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//
sourceBuilder.query(QueryBuilders.termQuery("targetType", "users"));
//
sourceBuilder.query(QueryBuilders.termQuery("messageType", "txt"));
//
sourceBuilder.from(0);
//
sourceBuilder.size(5);
//
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//
QueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("targetType", "users")
//
.fuzziness(Fuzziness.AUTO)
//
.prefixLength(3)
//
.maxExpansions(10);
//
sourceBuilder.query(matchQueryBuilder);
//
SimpleQueryStringBuilder simpleQueryStringBuilder = new SimpleQueryStringBuilder("users").field("targetType");
//
sourceBuilder.query(simpleQueryStringBuilder);
//
QueryStringQueryBuilder queryStringQueryBuilder = new QueryStringQueryBuilder("users").field("targetType");
//
sourceBuilder.query(queryStringQueryBuilder);
//
QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
//
sourceBuilder.query(queryBuilder);
//
SearchRequest searchRequest = new SearchRequest(esIndexImMessage);
//
searchRequest.types(esTypeImMessage);
//
searchRequest.source(sourceBuilder);
//
try {
//
SearchResponse searchResponse = client.search(searchRequest);
//
SearchHits hits = searchResponse.getHits();
//
long totalHits = hits.getTotalHits();
//
float maxScore = hits.getMaxScore();
//
SearchHit[] searchHits = hits.getHits();
//
for (SearchHit hit : searchHits) {
//
String index = hit.getIndex();
//
String type = hit.getType();
//
String id = hit.getId();
//
float score = hit.getScore();
//
//
取_source字段值
//
String sourceAsString = hit.getSourceAsString();
//
取成json串
//
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//
取成map对象
//
logger.info("totalHits:" + totalHits + " maxScore:" + maxScore + " index:" + index + " type:" + type + " id:" + id + " score:" + score);
//
logger.info(sourceAsString);
//
} catch (IOException e) {
//
e.printStackTrace();
StringBuilder entity
=
new
StringBuilder();
entity.append(
"{"
);
entity.append(getImMessageQueryPage(queryMap));
entity.append(
"\"query\" : {\"bool\" : { \"must\" : ["
);
entity.append(getImMessageQuerySearch(queryMap));
entity.append(getImMessageQueryRange(queryMap));
entity.append(
"]"
);
entity.append(getImMessageQueryFilter(queryMap));
entity.append(
"}}"
);
entity.append(getImMessageQueryString(queryMap));
entity.append(getImMessageQuerySort(queryMap));
entity.append(getImMessageQueryAggs());
entity.append(
"}"
);
logger.info(entity.toString());
//
queryMap = Collections.singletonMap("pretty", "true");
HttpEntity httpEntity
=
new
StringEntity(entity.toString(), "utf-8"
);
HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory
=
new
HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024
);
SearchImResultVo searchImResultVo
=
new
SearchImResultVo();
try
{
Response response
=
lowClient.performRequest(
"GET", "/" + esIndexImMessage + "/_search",
new
HashMap<>
(), httpEntity, consumerFactory);
String responseBody
=
EntityUtils.toString(response.getEntity());
JsonNode jsonNode
=
JsonHelper.toJsonNode(responseBody);
logger.info(responseBody);
searchImResultVo.setTotal(jsonNode.get(
"hits").get("total"
).asInt());
searchImResultVo.setResultList(getSearchImResultVoList(jsonNode.get(
"hits").get("hits"
)));
}
catch
(IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
return
searchImResultVo;
private
List<ImResultVo>
getSearchImResultVoList(JsonNode hitsNode) {
List
<ImResultVo> searchImResultVoList =
new
ArrayList<>
();
if
(hitsNode.isArray()) {
for
(JsonNode hit : hitsNode) {
searchImResultVoList.add(JsonHelper.toGenericObject(hit.get(
"_source").toString(),
new
TypeReference<ImResultVo>
() {
return
searchImResultVoList;
private
List<PostResultVo>
getSearchPostResultVoList(JsonNode hitsNode) {
List
<PostResultVo> searchPostResultList =
new
ArrayList<>
();
if
(hitsNode.isArray()) {
for
(JsonNode hit : hitsNode) {
searchPostResultList.add(JsonHelper.toGenericObject(hit.get(
"_source").toString(),
new
TypeReference<PostResultVo>
() {
return
searchPostResultList;
private
List<CommentResultVo>
getSearchCommentResultVoList(JsonNode hitsNode) {
List
<CommentResultVo> searchCommentResultList =
new
ArrayList<>
();
if
(hitsNode.isArray()) {
for
(JsonNode hit : hitsNode) {
searchCommentResultList.add(JsonHelper.toGenericObject(hit.get(
"_source").toString(),
new
TypeReference<CommentResultVo>
() {
return
searchCommentResultList;
//
public void update(String index, String type, String id, HashMap<String, Object> jsonMap) {
//
UpdateRequest updateRequest = new UpdateRequest(index, type, id).doc(jsonMap);
//
ActionListener<UpdateResponse> listener = new ActionListener<UpdateResponse>() {
//
@Override
//
public void onResponse(UpdateResponse updateResponse) {
//
//
如果执行成功,则调用onResponse方法;
//
logger.info(String.format("index %s", updateResponse.getGetResult()));
//
@Override
//
public void onFailure(Exception e) {
//
//
如果失败,则调用onFailure方法。
//
logger.error(e.getMessage());
//
};
//
client.updateAsync(updateRequest, listener);
public
<T>
boolean
bulkInsert(String index, String type, List<T>
list) {
boolean
bulkInsertResult =
false
;
BulkRequest request
=
new
BulkRequest();
request.timeout(TimeValue.timeValueMinutes(
2
));
request.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
request.waitForActiveShards(
2
);
for
(T t : list) {
String indexField
= t.getClass().getAnnotation(IndexAnnotation.
class
).field();
try
{
request.add(
new
IndexRequest(index, type, t.getClass().getDeclaredField(indexField).get(t).toString()).source(JsonHelper.toJson(t), XContentType.JSON));
}
catch
(NoSuchFieldException e) {
e.printStackTrace();
}
catch
(IllegalAccessException e) {
e.printStackTrace();
try
{
BulkResponse bulkResponse
=
client.bulk(request);
if
(!
bulkResponse.hasFailures()) {
bulkInsertResult
=
true
;
}
catch
(IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
return
bulkInsertResult;
public
<T>
void
insertOrUpdate(String index, String type, T t) {
try
{
String indexField
= t.getClass().getAnnotation(IndexAnnotation.
class
).field();
IndexRequest indexRequest
=
new
IndexRequest(index, type, t.getClass().getDeclaredField(indexField).get(t).toString());
indexRequest.source(JsonHelper.toJson(t), XContentType.JSON);
ActionListener
<IndexResponse> listener =
new
ActionListener<IndexResponse>
() {
@Override
public
void
onResponse(IndexResponse indexResponse) {
//
如果执行成功,则调用onResponse方法;
logger.info(String.format("%s %s %s"
, indexResponse.getIndex(), indexResponse.getId(), indexResponse.getResult()));
@Override
public
void
onFailure(Exception e) {
//
如果失败,则调用onFailure方法。
logger.error(e.getMessage());
client.indexAsync(indexRequest, listener);
}
catch
(NoSuchFieldException e) {
e.printStackTrace();
}
catch
(IllegalAccessException e) {
e.printStackTrace();
public
void
createImMessageIndex() {
//
先刪除再創建
deleteIndex(esIndexImMessage);
createIndex(esIndexImMessage, esTypeImMessage, createImMessageMapping());
public
void
createWantPostIndex() {
//
先刪除再創建
deleteIndex(esIndexWantPost);
createIndex(esIndexWantPost, esTypeWantPost, createWantPostMapping());
public
void
createWantCommentIndex() {
//
先刪除再創建
deleteIndex(esIndexWantComment);
createIndex(esIndexWantComment, esTypeWantComment, createWantCommentMapping());
public
boolean
deleteImMessageDocument(String id) {
return
deleteDocument(esIndexImMessage, esTypeImMessage, id);
public
boolean
deleteWantPostDocument(String id) {
return
deleteDocument(esIndexWantPost, esTypeWantPost, id);
public
boolean
deleteWantCommentDocument(String id) {
return
deleteDocument(esIndexWantComment, esTypeWantComment, id);
protected
String createWantCommentMapping() {
String json
= ""
;
try
{
XContentBuilder mapping
=
XContentFactory.jsonBuilder()
.startObject()
.startObject(esTypeWantComment)
.startObject(
"properties")
//
设置之定义字段
.startObject(
"commentId")
//
字段id
.field("type", "long")
//
设置数据类型
.field("index", "not_analyzed"
)
.endObject()
.startObject(
"commentType"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"commentChannel"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"content"
)
.field(
"type", "text"
)
.field(
"index", "analyzed"
)
.endObject()
.startObject(
"deep"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"relateStoreId"
)
.field(
"type", "integer"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"relateCommonId"
)
.field(
"type", "integer"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"relatePostId"
)
.field(
"type", "long"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"replyCommentId"
)
.field(
"type", "long"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"createBy"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"createTime"
)
.field(
"type", "date"
)
.field(
"index", "not_analyzed"
)
.field(
"format", "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
)
.endObject()
.startObject(
"commentState"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"commentLike"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"commentUnlike"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"commentFavor"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"commentReply"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"commentShare"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"images"
)
.field(
"type", "nested"
)
.endObject()
.endObject()
.endObject()
.endObject();
json
=
mapping.string();
}
catch
(IOException e) {
e.printStackTrace();
return
json;
protected
String createWantPostMapping() {
String json
= ""
;
try
{
XContentBuilder mapping
=
XContentFactory.jsonBuilder()
.startObject()
.startObject(esTypeWantPost)
.startObject(
"properties")
//
设置之定义字段
.startObject(
"postId")
//
字段id
.field("type", "long")
//
设置数据类型
.field("index", "not_analyzed"
)
.endObject()
.startObject(
"title"
)
.field(
"type", "text"
)
.field(
"index", "analyzed"
)
.endObject()
.startObject(
"content"
)
.field(
"type", "text"
)
.field(
"index", "analyzed"
)
.endObject()
.startObject(
"postCategory"
)
.field(
"type", "keyword"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"coverImage"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"postType"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"postTag"
)
.field(
"type", "text"
)
.field(
"index", "analyzed"
)
.endObject()
.startObject(
"keyword"
)
.field(
"type", "text"
)
.field(
"index", "analyzed"
)
.endObject()
.startObject(
"createTime"
)
.field(
"type", "date"
)
.field(
"index", "not_analyzed"
)
.field(
"format", "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
)
.endObject()
.startObject(
"createBy"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"isPublish"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"isDelete"
)
.field(
"type", "byte"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"expiresDate"
)
.field(
"type", "date"
)
.field(
"index", "not_analyzed"
)
.field(
"format", "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
)
.endObject()
.startObject(
"budgetPrice"
)
.field(
"type", "scaled_float"
)
.field(
"scaling_factor", "10"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"postView"
)
.field(
"type", "integer"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"postLike"
)
.field(
"type", "integer"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"postUnlike"
)
.field(
"type", "integer"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"postFavor"
)
.field(
"type", "integer"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"postReply"
)
.field(
"type", "integer"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"postShare"
)
.field(
"type", "integer"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"approveReason"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"comments"
)
.field(
"type", "nested"
)
.endObject()
.startObject(
"images"
)
.field(
"type", "nested"
)
.endObject()
.endObject()
.endObject()
.endObject();
json
=
mapping.string();
}
catch
(IOException e) {
e.printStackTrace();
return
json;
protected
String createImMessageMapping() {
String json
= ""
;
try
{
XContentBuilder mapping
=
XContentFactory.jsonBuilder()
.startObject()
.startObject(esTypeImMessage)
.startObject(
"properties")
//
设置之定义字段
.startObject(
"id")
//
字段id
.field("type", "long")
//
设置数据类型
.field("index", "not_analyzed"
)
.endObject()
.startObject(
"sendFrom"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"target"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"targetType"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"groupName"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"messageContent"
)
.field(
"type", "text"
)
.field(
"index", "analyzed"
)
.endObject()
.startObject(
"messageType"
)
.field(
"type", "text"
)
.field(
"index", "not_analyzed"
)
.endObject()
.startObject(
"sendTime"
)
.field(
"type", "date"
)
.field(
"index", "not_analyzed"
)
.field(
"format", "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
)
.endObject()
.endObject()
.endObject()
.endObject();
json
=
mapping.string();
}
catch
(IOException e) {
e.printStackTrace();
return
json;
protected
void
createIndex(String index, String type, String source) {
CreateIndexRequest request
=
new
CreateIndexRequest(index);
//
创建索引
//
创建的每个索引都可以有与之关联的特定设置。
request.settings(Settings.builder()
.put(
"index.number_of_shards", 5
)
.put(
"index.number_of_replicas", 1
)
//
创建索引时创建文档类型映射
request.mapping(type,
//
类型定义
source,
//
类型映射,需要的是一个JSON字符串
XContentType.JSON);
//
可选参数
request.timeout(TimeValue.timeValueMinutes(2));
//
超时,等待所有节点被确认(使用TimeValue方式)
request.masterNodeTimeout(TimeValue.timeValueMinutes(
1));
//
连接master节点的超时时间(使用TimeValue方式)
request.waitForActiveShards(
2);
//
在创建索引API返回响应之前等待的活动分片副本的数量,以int形式表示。
ActionListener
<CreateIndexResponse> listener =
new
ActionListener<CreateIndexResponse>
() {
@Override
public
void
onResponse(CreateIndexResponse createIndexResponse) {
//
如果执行成功,则调用onResponse方法;
logger.info(String.format("create %s mapping %s"
, createIndexResponse.index(), createIndexResponse.isAcknowledged()));
@Override
public
void
onFailure(Exception e) {
//
如果失败,则调用onFailure方法。
logger.error(e.getMessage());
client.indices().createAsync(request, listener);
//
要执行的CreateIndexRequest和执行完成时要使用的ActionListener
protected
boolean
deleteIndex(String index) {
boolean
acknowledged =
false
;
DeleteIndexRequest request
=
new
DeleteIndexRequest(index);
//
指定要删除的索引名称
//
可选参数:
request.timeout(TimeValue.timeValueMinutes(2));
//
设置超时,等待所有节点确认索引删除(使用TimeValue形式)
request.masterNodeTimeout(TimeValue.timeValueMinutes(
1));
////
连接master节点的超时时间(使用TimeValue方式)
//
设置IndicesOptions控制如何解决不可用的索引以及如何扩展通配符表达式
request.indicesOptions(IndicesOptions.lenientExpandOpen());
try
{
//
同步执行
DeleteIndexResponse deleteIndexResponse =
client.indices().delete(request);
//
返回的DeleteIndexResponse允许检索有关执行的操作的信息,如下所示:
acknowledged = deleteIndexResponse.isAcknowledged();
//
是否所有节点都已确认请求
}
catch
(ElasticsearchException e) {
if
(e.status() ==
RestStatus.NOT_FOUND) {
//
如果没有找到要删除的索引,要执行某些操作
}
catch
(IOException e) {
return
acknowledged;
protected
boolean
deleteDocument(String index, String type, String id) {
boolean
deleted =
false
;
DeleteRequest deleteRequest
=
new
DeleteRequest(index, type, id);
//
可选参数:
deleteRequest.timeout(TimeValue.timeValueMinutes(2
));
deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.WAIT_UNTIL);
try
{
//
同步执行
DeleteResponse deleteResponse =
client.delete(deleteRequest);
if
(deleteResponse.getResult() ==
DocWriteResponse.Result.NOT_FOUND) {
}
else
if
(deleteResponse.getResult() ==
DocWriteResponse.Result.DELETED) {
deleted
=
true
;
}
catch
(ElasticsearchException e) {
if
(e.status() ==
RestStatus.CONFLICT) {
}
catch
(IOException e) {
return
deleted;
private
String getImMessageQueryPage(HashMap<String, Object>
params) {
int
page = 0
;
int
size = 0
;
if
(params.containsKey("page"
)) {
String paramPage
= params.get("page"
).toString();
if
(!
Strings.isEmpty(paramPage)) {
page
=
Integer.valueOf(paramPage);
if
(params.containsKey("size"
)) {
String paramSize
= params.get("size"
).toString();
if
(!
Strings.isEmpty(paramSize)) {
size
=
Integer.valueOf(paramSize);
if
(page <= 0
) {
page
= 1
;
if
(size <= 0
) {
size
= 10
;
int
from = (page - 1) *
size;
return
"\"from\":" + from + ",\"size\":" + size + ","
;
private
String getImMessageQuerySearch(HashMap<String, Object>
params) {
if
(params.containsKey("messageContent"
)) {
return
"{\"match\": {\"messageContent\": \"" + params.get("messageContent") + "\"}}"
;
return
"{\"match_all\":{}}"
;
private
String getImMessageQueryRange(HashMap<String, Object>
params) {
String rangeString
= ""
;
if
(params.containsKey("sendTimeFrom"
)) {
rangeString
+= ",{\"range\": {\"sendTime\": {\"gte\": \"" + params.get("sendTimeFrom") + "\"}}}"
;
if
(params.containsKey("sendTimeTo"
)) {
rangeString
+= ",{\"range\": {\"sendTime\": {\"lte\": \"" + params.get("sendTimeTo") + "\"}}}"
;
if
(params.containsKey("idFrom"
)) {
rangeString
+= ",{\"range\": {\"id\": {\"gte\":" + params.get("idFrom") + "}}}"
;
if
(params.containsKey("idTo"
)) {
rangeString
+= ",{\"range\": {\"id\": {\"lte\":" + params.get("idTo") + "}}}"
;
return
rangeString;
private
String getImMessageQueryFilter(HashMap<String, Object>
params) {
String filterString
= ""
;
if
(params.containsKey("id"
)) {
filterString
+= ",{\"term\": { \"id\":" + params.get("id") + "}}"
;
if
(params.containsKey("sendFrom"
)) {
filterString
+= ",{\"term\": { \"sendFrom\":\"" + params.get("sendFrom") + "\"}}"
;
if
(params.containsKey("groupName"
)) {
filterString
+= ",{\"term\": { \"groupName\":\"" + params.get("groupName") + "\"}}"
;
if
(params.containsKey("messageType"
)) {
filterString
+= ",{\"term\": { \"messageType\":\"" + params.get("messageType") + "\"}}"
;
if
(params.containsKey("target"
)) {
filterString
+= ",{\"term\": { \"target\":\"" + params.get("target") + "\"}}"
;
if
(params.containsKey("targetType"
)) {
filterString
+= ",{\"term\": { \"targetType\":\"" + params.get("targetType") + "\"}}"
;
if
(!filterString.equals(""
)) {
filterString
= ",\"filter\": [" + filterString.substring(1, filterString.length()) + "]"
;
return
filterString;
private
String getImMessageQuerySort(HashMap<String, Object>
params) {
if
(params.containsKey("sort"
)) {
return
",\"sort\": [{\"" + params.get("sort"
)
+ "\":{\"order\": \"" + params.get("order"
)
+ "\"}}, {\"id\": {\"order\": \"desc\"}}]"
;
return
""
;
private
String getImMessageQueryAggs() {
return
",\"aggs\": { }"
;
private
String getImMessageQueryString(HashMap<String, Object>
params) {
if
(params.containsKey("query"
)) {
return
",\"query\": {\"query_string\": { \"query\":\"" + params.get("query") + "\"}}"
;
return
""
;
private
String getWantPostQueryPage(HashMap<String, Object>
params) {
int
page = 0
;
int
size = 0
;
if
(params.containsKey("page"
)) {
String paramPage
= params.get("page"
).toString();
if
(!
Strings.isEmpty(paramPage)) {
page
=
Integer.valueOf(paramPage);
if
(params.containsKey("size"
)) {
String paramSize
= params.get("size"
).toString();
if
(!
Strings.isEmpty(paramSize)) {
size
=
Integer.valueOf(paramSize);
if
(page <= 0
) {
page
= 1
;
if
(size <= 0
) {
size
= 10
;
int
from = (page - 1) *
size;
return
"\"from\":" + from + ",\"size\":" + size + ","
;
private
String getWantPostQuerySearch(HashMap<String, Object>
params) {
if
(params.containsKey("content"
)) {
return
"{\"match\": {\"content\": \"" + params.get("content") + "\"}}"
;
if
(params.containsKey("title"
)) {
return
"{\"match\": {\"title\": \"" + params.get("title") + "\"}}"
;
return
"{\"match_all\":{}}"
;
private
String getWantPostQueryRange(HashMap<String, Object>
params) {
String rangeString
= ""
;
if
(params.containsKey("createTimeFrom"
)) {
rangeString
+= ",{\"range\": {\"createTime\": {\"gte\": \"" + params.get("createTimeFrom") + "\"}}}"
;
if
(params.containsKey("createTimeTo"
)) {
rangeString
+= ",{\"range\": {\"createTime\": {\"lte\": \"" + params.get("createTimeTo") + "\"}}}"
;
if
(params.containsKey("expiresDateFrom"
)) {
rangeString
+= ",{\"range\": {\"expiresDate\": {\"gte\": \"" + params.get("expiresDateFrom") + "\"}}}"
;
if
(params.containsKey("expiresDateTo"
)) {
rangeString
+= ",{\"range\": {\"expiresDate\": {\"lte\": \"" + params.get("expiresDateTo") + "\"}}}"
;
if
(params.containsKey("budgetPriceFrom"
)) {
rangeString
+= ",{\"range\": {\"budgetPrice\": {\"lte\": " + params.get("budgetPriceFrom") + "}}}"
;
if
(params.containsKey("budgetPriceTo"
)) {
rangeString
+= ",{\"range\": {\"budgetPrice\": {\"lte\": " + params.get("budgetPriceTo") + "}}}"
;
if
(params.containsKey("postIdFrom"
)) {
rangeString
+= ",{\"range\": {\"postId\": {\"gte\":" + params.get("postIdFrom") + "}}}"
;
if
(params.containsKey("postIdTo"
)) {
rangeString
+= ",{\"range\": {\"postId\": {\"lte\":" + params.get("postIdTo") + "}}}"
;
return
rangeString;
private
String getWantPostQueryFilterPhrase(HashMap<String, Object>
params){
String phraseString
= ""
;
if
(params.containsKey("postTag"
)) {
phraseString
+= ",{\"match_phrase\": { \"postTag\":\"" + params.get("postTag") + "\"}}"
;
if
(params.containsKey("keyword"
)) {
phraseString
+= ",{\"match_phrase\": { \"keyword\":\"" + params.get("keyword") + "\"}}"
;
return
phraseString;
private
String getWantPostQueryFilter(HashMap<String, Object>
params) {
String filterString
= ""
;
if
(params.containsKey("postId"
)) {
filterString
+= ",{\"term\": { \"postId\":" + params.get("postId") + "}}"
;
if
(params.containsKey("postCategory"
)) {
filterString
+= ",{\"term\": { \"postCategory\":\"" + params.get("postCategory") + "\"}}"
;
if
(params.containsKey("postType"
)) {
filterString
+= ",{\"term\": { \"postType\":\"" + params.get("postType") + "\"}}"
;
if
(params.containsKey("createBy"
)) {
filterString
+= ",{\"term\": { \"createBy\":\"" + params.get("createBy") + "\"}}"
;
if
(params.containsKey("isPublish"
)) {
filterString
+= ",{\"term\": { \"isPublish\":\"" + params.get("isPublish") + "\"}}"
;
if
(params.containsKey("isDelete"
)) {
filterString
+= ",{\"term\": { \"isDelete\":\"" + params.get("isDelete") + "\"}}"
;
if
(!filterString.equals(""
)) {
filterString
= ",\"filter\": [" + filterString.substring(1, filterString.length()) + "]"
;
return
filterString;
private
String getWantPostQuerySort(HashMap<String, Object>
params) {
if
(params.containsKey("sort"
)) {
return
",\"sort\": [{\"" + params.get("sort"
)
+ "\":{\"order\": \"" + params.get("order"
)
+ "\"}}, {\"postId\": {\"order\": \"desc\"}}]"
;
return
""
;
private
String getWantPostQueryAggs() {
return
",\"aggs\": { }"
;
private
String getWantPostQueryString(HashMap<String, Object>
params) {
if
(params.containsKey("query"
)) {
return
",\"query\": {\"query_string\": { \"query\":\"" + params.get("query") + "\"}}"
;
return
""
;
private
String getWantPostQuerySource(HashMap<String, Object>
params) {
if
(params.containsKey("source"
)) {
return
",\"_source\": " + JsonHelper.toJson(params.get("source"
));
return
",\"_source\": []"
;
private
String getWantCommentQueryPage(HashMap<String, Object>
params) {
int
page = 0
;
int
size = 0
;
if
(params.containsKey("page"
)) {
String paramPage
= params.get("page"
).toString();
if
(!
Strings.isEmpty(paramPage)) {
page
=
Integer.valueOf(paramPage);
if
(params.containsKey("size"
)) {
String paramSize
= params.get("size"
).toString();
if
(!
Strings.isEmpty(paramSize)) {
size
=
Integer.valueOf(paramSize);
if
(page <= 0
) {
page
= 1
;
if
(size <= 0
) {
size
= 10
;
int
from = (page - 1) *
size;
return
"\"from\":" + from + ",\"size\":" + size + ","
;
private
String getWantCommentQuerySearch(HashMap<String, Object>
params) {
if
(params.containsKey("content"
)) {
return
"{\"match\": {\"content\": \"" + params.get("content") + "\"}}"
;
return
"{\"match_all\":{}}"
;
private
String getWantCommentQueryRange(HashMap<String, Object>
params) {
String rangeString
= ""
;
if
(params.containsKey("createTimeFrom"
)) {
rangeString
+= ",{\"range\": {\"createTime\": {\"gte\": \"" + params.get("createTimeFrom") + "\"}}}"
;
if
(params.containsKey("createTimeTo"
)) {
rangeString
+= ",{\"range\": {\"createTime\": {\"lte\": \"" + params.get("createTimeTo") + "\"}}}"
;
if
(params.containsKey("commentIdFrom"
)) {
rangeString
+= ",{\"range\": {\"commentId\": {\"gte\":" + params.get("commentIdFrom") + "}}}"
;
if
(params.containsKey("commentIdTo"
)) {
rangeString
+= ",{\"range\": {\"commentId\": {\"lte\":" + params.get("commentIdTo") + "}}}"
;
return
rangeString;
private
String getWantCommentQueryFilter(HashMap<String, Object>
params) {
String filterString
= ""
;
if
(params.containsKey("commentId"
)) {
filterString
+= ",{\"term\": { \"commentId\":" + params.get("commentId") + "}}"
;
if
(params.containsKey("commentType"
)) {
filterString
+= ",{\"term\": { \"commentType\":" + params.get("commentType") + "}}"
;
if
(params.containsKey("commentChannel"
)) {
filterString
+= ",{\"term\": { \"commentChannel\":" + params.get("commentChannel") + "}}"
;
if
(params.containsKey("deep"
)) {
filterString
+= ",{\"term\": { \"deep\":" + params.get("deep") + "}}"
;
if
(params.containsKey("relateStoreId"
)) {
filterString
+= ",{\"term\": { \"relateStoreId\":" + params.get("relateStoreId") + "}}"
;
if
(params.containsKey("relateCommonId"
)) {
filterString
+= ",{\"term\": { \"relateCommonId\":" + params.get("relateCommonId") + "}}"
;
if
(params.containsKey("relatePostId"
)) {
filterString
+= ",{\"term\": { \"relatePostId\":" + params.get("relatePostId") + "}}"
;
if
(params.containsKey("replyCommentId"
)) {
filterString
+= ",{\"term\": { \"replyCommentId\":" + params.get("replyCommentId") + "}}"
;
if
(params.containsKey("commentState"
)) {
filterString
+= ",{\"term\": { \"commentState\":" + params.get("commentState") + "}}"
;
if
(params.containsKey("createBy"
)) {
filterString
+= ",{\"term\": { \"createBy\":\"" + params.get("createBy") + "\"}}"
;
if
(!filterString.equals(""
)) {
filterString
= ",\"filter\": [" + filterString.substring(1, filterString.length()) + "]"
;
return
filterString;
private
String getWantCommentQuerySort(HashMap<String, Object>
params) {
if
(params.containsKey("sort"
)) {
return
",\"sort\": [{\"" + params.get("sort"
)
+ "\":{\"order\": \"" + params.get("order"
)
+ "\"}}, {\"commentId\": {\"order\": \"desc\"}}]"
;
return
""
;
private
String getWantCommentQueryAggs() {
return
",\"aggs\": { }"
;
private
String getWantCommentQueryString(HashMap<String, Object>
params) {
if
(params.containsKey("query"
)) {
return
",\"query\": {\"query_string\": { \"query\":\"" + params.get("query") + "\"}}"
;
return
""
;
@PostConstruct
protected
void
init() {
client
=
new
RestHighLevelClient(
RestClient.builder(
new
HttpHost(esHost, esPort, esScheme)));
lowClient
=
RestClient.builder(
new
HttpHost(esHost, esPort, esScheme)).build();
@PreDestroy
protected
void
destroy() {
if
(client !=
null
) {
try
{
client.close();
}
catch
(IOException e) {
e.printStackTrace();
if
(lowClient !=
null
) {
try
{
lowClient.close();
}
catch
(IOException e) {
e.printStackTrace();
ESRestService
package com.ftofs.esclient.service;
import com.ftofs.esclient.dao.ImMessageLogRepository;
import com.ftofs.esclient.dao.WantCommentImageRepository;
import com.ftofs.esclient.dao.WantCommentRepository;
import com.ftofs.esclient.dao.WantPostImageRepository;
import com.ftofs.esclient.dao.WantPostRepository;
import com.ftofs.esclient.domain.ImMessageLog;
import com.ftofs.esclient.domain.WantComment;
import com.ftofs.esclient.domain.WantPost;
import com.ftofs.esclient.vo.CommentImageResultVo;
import com.ftofs.esclient.vo.CommentResultVo;
import com.ftofs.esclient.vo.ImResultVo;
import com.ftofs.esclient.vo.PostImageResultVo;
import com.ftofs.esclient.vo.PostResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
@Component
public class ReindexService {
@Autowired
private WantPostRepository wantPostRepository;
@Autowired
private WantCommentRepository wantCommentRepository;
@Autowired
private WantPostImageRepository wantPostImageRepository;
@Autowired
private WantCommentImageRepository wantCommentImageRepository;
@Autowired
private ImMessageLogRepository imMessageLogRepository;
private <T> String emptyToNull(T value) {
if (value == null) {
return null;
} else {
return String.valueOf(value);
* 重置所有IM消息記錄
* @return
public List<ImResultVo> getImMessageResultVoList() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List<ImResultVo> imResultVoList = new ArrayList<>();
List<ImMessageLog> imMessageLogList = imMessageLogRepository.findAll();
imMessageLogList.forEach(x -> {
ImResultVo imResultVo = new ImResultVo();
imResultVo.setGroupName(x.getGroupName());
imResultVo.setId(String.valueOf(x.getId()));
imResultVo.setMessageContent(x.getMessageContent());
imResultVo.setMessageType(x.getMessageType());
imResultVo.setSendFrom(x.getSendFrom());
imResultVo.setSendTime(sdf.format(x.getSendTime()));
imResultVo.setTarget(x.getTarget());
imResultVo.setTargetType(x.getTargetType());
imResultVoList.add(imResultVo);
return imResultVoList;
* 重置所有評論記錄
* @return
public List<CommentResultVo> getCommentResultVoList() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
List<CommentResultVo> commentResultVoList = new ArrayList<>();
List<WantComment> wantCommentList = wantCommentRepository.findAll();
wantCommentList.forEach(x -> {
CommentResultVo commentResultVo = new CommentResultVo();
commentResultVo.setReplyCommentId(emptyToNull(x.getReplyCommentId()));
commentResultVo.setRelateStoreId(emptyToNull(x.getRelateStoreId()));
commentResultVo.setRelatePostId(emptyToNull(x.getRelateStoreId()));
commentResultVo.setRelateCommonId(emptyToNull(x.getRelateCommonId()));
commentResultVo.setDeep(emptyToNull(x.getDeep()));
commentResultVo.setCommentUnlike(emptyToNull(x.getCommentUnlike()));
commentResultVo.setCommentType(emptyToNull(x.getCommentType()));
commentResultVo.setCommentState(emptyToNull(x.getCommentState()));
commentResultVo.setCommentShare(emptyToNull(x.getCommentShare()));
commentResultVo.setCommentReply(emptyToNull(x.getCommentReply()));
commentResultVo.setCommentLike(emptyToNull(x.getCommentLike()));
commentResultVo.setCommentId(emptyToNull(x.getCommentId()));
commentResultVo.setCommentFavor(emptyToNull(x.getCommentFavor()));
commentResultVo.setCommentChannel(emptyToNull(x.getCommentChannel()));
commentResultVo.setCreateTime(sdf.format(x.getCreateTime()));
commentResultVo.setCreateBy(x.getCreateBy());
commentResultVo.setContent(x.getContent());
List<CommentImageResultVo> commentImages = new ArrayList<>();
List<String> imageUrlList = wantCommentImageRepository.findWantCommentImagesByCommentId(x.getCommentId());
imageUrlList.forEach(url -> {
CommentImageResultVo commentImageResultVo = new CommentImageResultVo();
commentImageResultVo.setImageUrl(url);
commentImages.add(commentImageResultVo);
commentResultVo.setImages(commentImages);
commentResultVoList.add(commentResultVo);
return commentResultVoList;
* 重置所有貼文記錄
* @return
public List<PostResultVo> getPostResultVoList() {
SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
List<PostResultVo> postResultVoList = new ArrayList<>();
List<WantPost> wantPostList = wantPostRepository.findAll();
wantPostList.forEach(x -> {
PostResultVo postResultVo = new PostResultVo();
postResultVo.setBudgetPrice(emptyToNull(x.getBudgetPrice()));
postResultVo.setContent(x.getContent());
postResultVo.setCreateBy(x.getCreateBy());
postResultVo.setCreateTime(sdfDateTime.format(x.getCreateTime()));
postResultVo.setExpiresDate(sdfDate.format(x.getExpiresDate()));
postResultVo.setIsDelete(emptyToNull(x.getIsDelete()));
postResultVo.setIsPublish(emptyToNull(x.getIsPublish()));
postResultVo.setKeyword(x.getKeyword());
postResultVo.setPostCategory(x.getPostCategory());
postResultVo.setPostId(emptyToNull(x.getPostId()));
postResultVo.setPostTag(x.getPostTag());
postResultVo.setPostType(emptyToNull(x.getPostType()));
postResultVo.setPostFavor(emptyToNull(x.getPostFavor()));
postResultVo.setPostLike(emptyToNull(x.getPostLike()));
postResultVo.setPostUnlike(emptyToNull(x.getPostUnlike()));
postResultVo.setPostShare(emptyToNull(x.getPostShare()));
postResultVo.setPostReply(emptyToNull(x.getPostReply()));
postResultVo.setPostView(emptyToNull(x.getPostView()));
postResultVo.setTitle(x.getTitle());
postResultVo.setCoverImage(x.getCoverImage());
postResultVo.setApproveReason(x.getApproveReason());
List<CommentResultVo> comments = new ArrayList<>();
List<WantComment> wantCommentList = wantCommentRepository.findWantCommentsByPostId(x.getPostId());
wantCommentList.forEach(y -> {
CommentResultVo commentResultVo = new CommentResultVo();
commentResultVo.setContent(y.getContent());
commentResultVo.setCreateBy(y.getCreateBy());
commentResultVo.setCreateTime(sdfDateTime.format(y.getCreateTime()));
commentResultVo.setCommentChannel(emptyToNull(y.getCommentChannel()));
commentResultVo.setCommentFavor(emptyToNull(y.getCommentFavor()));
commentResultVo.setCommentId(emptyToNull(y.getCommentId()));
commentResultVo.setCommentLike(emptyToNull(y.getCommentLike()));
commentResultVo.setCommentReply(emptyToNull(y.getCommentReply()));
commentResultVo.setCommentShare(emptyToNull(y.getCommentShare()));
commentResultVo.setCommentState(emptyToNull(y.getCommentState()));
commentResultVo.setCommentType(emptyToNull(y.getCommentType()));
commentResultVo.setCommentUnlike(emptyToNull(y.getCommentUnlike()));
commentResultVo.setDeep(emptyToNull(y.getDeep()));
commentResultVo.setRelateCommonId(emptyToNull(y.getRelateCommonId()));
commentResultVo.setRelatePostId(emptyToNull(y.getRelatePostId()));
commentResultVo.setRelateStoreId(emptyToNull(y.getRelateStoreId()));
commentResultVo.setReplyCommentId(emptyToNull(y.getReplyCommentId()));
List<CommentImageResultVo> commentImages = new ArrayList<>();
List<String> imageUrlList = wantCommentImageRepository.findWantCommentImagesByCommentId(y.getCommentId());
imageUrlList.forEach(url -> {
CommentImageResultVo commentImageResultVo = new CommentImageResultVo();
commentImageResultVo.setImageUrl(url);
commentImages.add(commentImageResultVo);
commentResultVo.setImages(commentImages);
comments.add(commentResultVo);
postResultVo.setComments(comments);
List<PostImageResultVo> postImages = new ArrayList<>();
List<String> imageUrlList = wantPostImageRepository.findWantPostImagesByPostId(x.getPostId());
imageUrlList.forEach(url -> {
PostImageResultVo postImageResultVo = new PostImageResultVo();
postImageResultVo.setImageUrl(url);
postImages.add(postImageResultVo);
postResultVo.setImages(postImages);
postResultVoList.add(postResultVo);
return postResultVoList;
ReindexService
package com.ftofs.esclient.common;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class ESAnnotation {
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface IndexAnnotation {
String field();
ESAnnotation
package com.ftofs.esclient.common;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
* JSON帮助类
public class JsonHelper {
private static final Logger log = LoggerFactory.getLogger(JsonHelper.class);
final static ObjectMapper objectMapper;
static {
objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
public static ObjectMapper getObjectMapper() {
return objectMapper;
* JSON串转换为Java泛型对象
* @param <T>
* @param jsonString JSON字符串
* @param tr TypeReference,例如: new TypeReference< List<FamousUser> >(){}
* @return List对象列表
public static <T> T toGenericObject(String jsonString, TypeReference<T> tr) {
if (jsonString == null || "".equals(jsonString)) {
return null;
} else {
try {
return (T) objectMapper.readValue(jsonString, tr);
} catch (Exception e) {
log.warn(jsonString);
log.warn("json error:" + e.getMessage());
return null;
* Json字符串转Java对象
* @param jsonString
* @param c
* @return
public static Object toObject(String jsonString, Class<?> c) {
if (jsonString == null || "".equals(jsonString)) {
return "";
} else {
try {
return objectMapper.readValue(jsonString, c);
} catch (Exception e) {
log.warn("json error:" + e.getMessage());
return null;
* Java对象转Json字符串
* @param object Java对象,可以是对象,数组,List,Map等
* @return json 字符串
public static String toJson(Object object) {
String jsonString = "";
try {
jsonString = objectMapper.writeValueAsString(object);
} catch (Exception e) {
log.warn("json error:" + e.getMessage());
return jsonString;
* Json字符串转JsonNode
* @param jsonString
* @return
public static JsonNode toJsonNode(String jsonString) {
try {
return objectMapper.readTree(jsonString);
} catch (IOException e) {
e.printStackTrace();
log.warn("json error:" + e.getMessage());
return null;
JsonHelper
package com.ftofs.esclient.controller;
import com.ftofs.esclient.ESRestService;
import com.ftofs.esclient.service.ReindexService;
import com.ftofs.esclient.vo.CommentResultVo;
import com.ftofs.esclient.vo.ImResultVo;
import com.ftofs.esclient.vo.PostResultVo;
import com.ftofs.esclient.vo.SearchCommentResultVo;
import com.ftofs.esclient.vo.SearchImResultVo;
import com.ftofs.esclient.vo.SearchPostResultVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
@RestController
@RequestMapping("")
@Api(tags="ESRestController")
public class ESRestController {
@Autowired
private ESRestService restService;
@Autowired
private ReindexService reindexService;
@Value("${esIndexImMessage}")
private String esIndexImMessage;
@Value("${esTypeImMessage}")
private String esTypeImMessage;
@Value("${esIndexWantPost}")
private String esIndexWantPost;
@Value("${esTypeWantPost}")
private String esTypeWantPost;
@Value("${esIndexWantComment}")
private String esIndexWantComment;
@Value("${esTypeWantComment}")
private String esTypeWantComment;
@PostMapping("/im/init")
@ApiOperation(value = "IM消息索引初始化")
public void imMessageInit() {
restService.createImMessageIndex();
@PostMapping("/im/delete/{id}")
@ApiOperation(value = "刪除IM消息")
public void deleteImMessageDocument(@PathVariable String id) {
restService.deleteImMessageDocument(id);
@PostMapping("/post/init")
@ApiOperation(value = "貼文索引初始化")
public void wantPostInit() {
restService.createWantPostIndex();
@PostMapping("/post/delete/{id}")
@ApiOperation(value = "刪除貼文")
public void deleteWantPostDocument(@PathVariable String id) {
restService.deleteWantPostDocument(id);
@PostMapping("/comment/init")
@ApiOperation(value = "評論索引初始化")
public void wantCommentInit() {
restService.createWantCommentIndex();
@PostMapping("/comment/delete/{id}")
@ApiOperation(value = "刪除評論")
public void deleteWantCommentDocument(@PathVariable String id) {
restService.deleteWantCommentDocument(id);
@PostMapping("/im/reindexRange")
@ApiOperation(value = "批量添加IM消息記錄")
public void imReindexRange(@RequestBody List<ImResultVo> imResultVoList) {
restService.imReindexRange(imResultVoList);
@PostMapping("/post/reindexRange")
@ApiOperation(value = "批量添加貼文")
public void postReindexRange(@RequestBody List<PostResultVo> postResultVoList) {
restService.postReindexRange(postResultVoList);
@PostMapping("/comment/reindexRange")
@ApiOperation(value = "批量添加評論")
public void commentReindexRange(@RequestBody List<CommentResultVo> commentResultVoList) {
restService.commentReindexRange(commentResultVoList);
@PostMapping("/im/insertOrUpdate")
@ApiOperation(value = "添加IM消息")
public void imMessageInsertOrUpdate(@RequestBody ImResultVo imResultVo) {
restService.insertOrUpdate(esIndexImMessage, esTypeImMessage, imResultVo);
@PostMapping("/post/insertOrUpdate")
@ApiOperation(value = "添加貼文")
public void wantPostInsertOrUpdate(@RequestBody PostResultVo postResultVo) {
restService.insertOrUpdate(esIndexWantPost, esTypeWantPost, postResultVo);
@PostMapping("/comment/insertOrUpdate")
@ApiOperation(value = "添加評論")
public void wantCommentInsertOrUpdate(@RequestBody CommentResultVo commentResultVo) {
restService.insertOrUpdate(esIndexWantComment, esTypeWantComment, commentResultVo);
@GetMapping("/im/search")
@ApiOperation(value = "IM消息搜索")
public SearchImResultVo imMessageSearch(@RequestBody HashMap<String, Object> queryMap) {
return restService.imMessageSearch(queryMap);
@GetMapping("/post/search")
@ApiOperation(value = "貼文搜索")
public SearchPostResultVo wantPostSearch(@RequestBody HashMap<String, Object> queryMap) {
return restService.wantPostSearch(queryMap);
@GetMapping("/comment/search")
@ApiOperation(value = "評論搜索")
public SearchCommentResultVo wantCommentSearch(@RequestBody HashMap<String, Object> queryMap) {
return restService.wantCommentSearch(queryMap);
@PostMapping("/im/reindexAll")
@ApiOperation(value = "重置所有IM消息記錄")
public void imReindexAll() {
restService.imReindexRange(reindexService.getImMessageResultVoList());
@PostMapping("/post/reindexAll")
@ApiOperation(value = "重置所有貼文記錄")
public void postReindexAll() {
restService.postReindexRange(reindexService.getPostResultVoList());
@PostMapping("/comment/reindexAll")
@ApiOperation(value = "重置所有評論記錄")
public void commentReindexAll() {
restService.commentReindexRange(reindexService.getCommentResultVoList());
ESRestController
package com.ftofs.esclient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@EnableSwagger2
@Configuration
public class Swagger2 {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.ftofs.esclient.controller"))
.paths(PathSelectors.any())
.build();
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Elasticsearch Rest High/Low Level Client 接口文檔說明")
.contact(new Contact("Nick.Chung", "http://cnblogs.com/ncore", "46638441@qq.com"))
.description("简单优雅的Restful风格")
.termsOfServiceUrl("https://github.com/mbhybird")
.version("1.0")
.build();
Swagger2
package com.ftofs.esclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ESClientApplication {
public static void main(String[] args) {
SpringApplication.run(ESClientApplication.class, args);
ESClientApplication
server.port=9500
esHost = 127.0.0.1
#dev:192.168.5.30
#train:192.168.5.32
esPort = 9200
esScheme = http
esIndexImMessage = index_im_msg
esIndexWantPost = index_want_post
esIndexWantComment = index_want_comment
esTypeImMessage = im_msg
esTypeWantPost = want_post
esTypeWantComment = want_comment
spring.datasource.url = jdbc:mysql://192.168.5.30:3306/twdb?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5Dialect
#logging.level.root=WARN
##logging.level.org.springframework.web=INFO
##logging.file=/log/es.log
##logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n
##logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
application.properties
<?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 http://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.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ftofs</groupId>
<artifactId>esclient</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>esclient</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.2.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>6.2.4</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.2.4</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<configuration>
<relocations>
<relocation>
<pattern>org.apache.http</pattern>
<shadedPattern>hidden.org.apache.http</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.logging</pattern>
<shadedPattern>hidden.org.apache.logging</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons.codec</pattern>
<shadedPattern>hidden.org.apache.commons.codec</shadedPattern>
</relocation>
<relocation>
<pattern>org.apache.commons.logging</pattern>
<shadedPattern>hidden.org.apache.commons.logging</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
pom.xml