From 98088e541ce4a4a5a9b3c5e2bc603a6e84b5d157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=BC=8A=E5=8D=9A?= <527515025@qq.com> Date: Thu, 2 Apr 2020 18:20:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9springboot-es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- springboot-elasticsearch/README.md | 9 + springboot-elasticsearch/pom.xml | 9 +- .../src/main/java/cn/abel/bean/User.java | 19 ++ .../cn/abel/config/ESRestClient2Config.java | 48 +++++ .../cn/abel/config/ESRestClientConfig.java | 5 +- .../java/cn/abel/service/UserService.java | 191 +++++++++++++++++- .../resources/local/application.properties | 9 +- 7 files changed, 279 insertions(+), 11 deletions(-) create mode 100644 springboot-elasticsearch/README.md create mode 100644 springboot-elasticsearch/src/main/java/cn/abel/config/ESRestClient2Config.java diff --git a/springboot-elasticsearch/README.md b/springboot-elasticsearch/README.md new file mode 100644 index 0000000..90a60de --- /dev/null +++ b/springboot-elasticsearch/README.md @@ -0,0 +1,9 @@ + +## springboot-elasticsearch + +* 本项目是speingboot结合es 的小李子。 +* 演示了同一个项目配置多个es 数据源 +* es操作是用es的rest api 进行操作,操作语句是 通过 JSONObject 对象进行拼接,可以执行增、删、改、查 行为。 +具体的操作命令可以查看 Es RESTful API 官方文档 + +https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html \ No newline at end of file diff --git a/springboot-elasticsearch/pom.xml b/springboot-elasticsearch/pom.xml index 9983a63..bcf0f44 100644 --- a/springboot-elasticsearch/pom.xml +++ b/springboot-elasticsearch/pom.xml @@ -52,16 +52,11 @@ 3.4 - - com.sun.jna - jna - 3.0.9 - org.elasticsearch.client - rest - 5.5.3 + elasticsearch-rest-client + 6.8.0 diff --git a/springboot-elasticsearch/src/main/java/cn/abel/bean/User.java b/springboot-elasticsearch/src/main/java/cn/abel/bean/User.java index 58acdf2..e1ddbf5 100644 --- a/springboot-elasticsearch/src/main/java/cn/abel/bean/User.java +++ b/springboot-elasticsearch/src/main/java/cn/abel/bean/User.java @@ -11,6 +11,9 @@ public class User { private String email; private Date createTime; private Integer role; + private String idCard; + private int type; + public Integer getId() { return id; @@ -67,4 +70,20 @@ public Integer getRole() { public void setRole(Integer role) { this.role = role; } + + public String getIdCard() { + return idCard; + } + + public void setIdCard(String idCard) { + this.idCard = idCard; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } } \ No newline at end of file diff --git a/springboot-elasticsearch/src/main/java/cn/abel/config/ESRestClient2Config.java b/springboot-elasticsearch/src/main/java/cn/abel/config/ESRestClient2Config.java new file mode 100644 index 0000000..694d8d6 --- /dev/null +++ b/springboot-elasticsearch/src/main/java/cn/abel/config/ESRestClient2Config.java @@ -0,0 +1,48 @@ +package cn.abel.config; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestClientBuilder; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 第二数据源 + * @author yyb + * @time 2020/4/2 + */ +@Configuration +public class ESRestClient2Config { + public static final String NAME = "ESRestClient2Config"; + + @Value("${elasticsearch2.userName}") + private String userName; + @Value("${elasticsearch2.password}") + private String password; + @Value("${elasticsearch2.rest.hostNames}") + private String hostName; + @Value("${elasticsearch2.rest.port}") + private Integer port; + + @Bean(name = NAME, destroyMethod = "close") + public RestClient getRestClient() { + final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(AuthScope.ANY, + new UsernamePasswordCredentials(userName, password)); + RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(hostName, port)); + //配置身份验证 + restClientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() { + @Override + public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) { + return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider); + } + }); + return restClientBuilder.build(); + } +} diff --git a/springboot-elasticsearch/src/main/java/cn/abel/config/ESRestClientConfig.java b/springboot-elasticsearch/src/main/java/cn/abel/config/ESRestClientConfig.java index af260fe..8f122ab 100644 --- a/springboot-elasticsearch/src/main/java/cn/abel/config/ESRestClientConfig.java +++ b/springboot-elasticsearch/src/main/java/cn/abel/config/ESRestClientConfig.java @@ -13,11 +13,14 @@ import org.springframework.context.annotation.Configuration; /** + * 第一数据源 * @author yangyibo * @time 2019/4/2 */ @Configuration public class ESRestClientConfig { + public static final String NAME = "ESRestClientConfig"; + @Value("${elasticsearch.userName}") private String userName; @Value("${elasticsearch.password}") @@ -27,7 +30,7 @@ public class ESRestClientConfig { @Value("${elasticsearch.rest.port}") private Integer port; - @Bean(destroyMethod = "close") + @Bean(name = NAME, destroyMethod = "close") public RestClient getRestClient() { final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, diff --git a/springboot-elasticsearch/src/main/java/cn/abel/service/UserService.java b/springboot-elasticsearch/src/main/java/cn/abel/service/UserService.java index 99f3c4b..10f08f2 100644 --- a/springboot-elasticsearch/src/main/java/cn/abel/service/UserService.java +++ b/springboot-elasticsearch/src/main/java/cn/abel/service/UserService.java @@ -1,31 +1,62 @@ package cn.abel.service; +import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Map; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import cn.abel.config.ESRestClient2Config; +import cn.abel.config.ESRestClientConfig; import cn.abel.constants.Constants; +import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.ContentType; import org.apache.http.nio.entity.NStringEntity; import org.apache.http.util.EntityUtils; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; +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.Service; import cn.abel.dao.UserDao; import cn.abel.bean.User; +/** + * @author yyb + */ @Service public class UserService { + private static final Logger logger = LoggerFactory.getLogger(UserService.class); + protected static final ObjectMapper mapper = new ObjectMapper(); + @Autowired private UserDao userDao; + + /** + * 数据源1 + */ @Autowired + @Qualifier(ESRestClientConfig.NAME) private RestClient restClient; + /** + * 数据源2 + */ + @Autowired + @Qualifier(ESRestClient2Config.NAME) + private RestClient restClient2; + + public List getByMap(Map map) { return userDao.getByMap(map); } @@ -41,6 +72,43 @@ public User getById(Integer id) throws Exception { return userDao.getById(id); } + + /** + * 查询用户列表 + * + * @param keyword 关键字用户名字/用户手机号/用户身份证号 + * @param type 用户类型/1:注册用户/2:转化用户 + * @param startTime 时间范围 起始时间 + * @param endTime 时间范围 结束时间 + * @param pageSize + * @param pageIndex + * @return + * @throws Exception + */ + public JSONObject getList(String keyword, Integer type, String startTime, String endTime, int pageSize, int pageIndex) throws Exception { + JsonNode searchResponse; + JSONObject response = new JSONObject(); + JSONObject search = searchListQuery(keyword, type, startTime, endTime, pageSize, pageIndex); + //根据档案英文名切换不同的索引 + String endpoint = "/user_Info_index/user/_search"; + + searchResponse = esSearch(search, endpoint, restClient); + if (null == searchResponse) { + return response; + } + JsonNode hitsNode = searchResponse.get("hits"); + ArrayNode hitsArray = (ArrayNode) hitsNode.get("hits"); + response.put("total", hitsNode.get("total").intValue()); + JSONArray list = new JSONArray(); + for (JsonNode hit : hitsArray) { + JSONObject result = (JSONObject) JSONObject.parse(hit.get("_source").toString()); + list.add(result); + } + response.put("list", list); + return response; + } + + public User create(User user) { userDao.create(user); return user; @@ -55,4 +123,123 @@ public int delete(Integer id) { return userDao.delete(id); } + + /** + * 拼装列表查询query + * + * @param keyword + * @return + */ + private JSONObject searchListQuery(String keyword, Integer type, String startTime, String endTime, int pageSize, int pageIndex) { + //只返回列表所需数据 + String[] source = new String[]{"id", "user_name", "id_card", "user_name", "mobile", "type", "create_time"}; + JSONObject search = new JSONObject(); + search.put("_source", source); + if (pageIndex <= 0) { + pageIndex = 1; + } + JSONObject bool = new JSONObject(); + JSONArray sort = new JSONArray(); + + //查询类型 + JSONArray mustArray = new JSONArray(); + if (null != type) { + mustArray.add(getJSONObject("term", getJSONObject("type", type))); + } + bool.put("must", mustArray); + + //关键字查询 + if (StringUtils.isNotEmpty(keyword)) { + JSONObject multiMatch = new JSONObject(); + multiMatch.put("query", keyword); + multiMatch.put("fields", new String[]{"user_name.keyword", "user_name"}); + //查询条件 + JSONArray shouldArray = new JSONArray(); + //虚化查询 + shouldArray.add(getJSONObject("term", getJSONObject("id_card", keyword))); + shouldArray.add(getJSONObject("term", getJSONObject("mobile", keyword))); + shouldArray.add(getJSONObject("multi_match", multiMatch)); + //关键字评分排序 + sort.add(getJSONObject("_score", getJSONObject("order", "desc"))); + //should 必须命中一个 + bool.put("minimum_should_match", 1); + bool.put("should", shouldArray); + } + + //排序和时间过滤 + JSONObject rangeField = new JSONObject(); + //筛选创建时间大于 startTime 小于 endTime 的数据 + rangeField.put("gte", startTime); + rangeField.put("lte", endTime); + JSONObject range = new JSONObject(); + range.put("range", getJSONObject("create_time", rangeField)); + //按照创建时间规则倒叙排序 + sort.add(getJSONObject("create_time", getJSONObject("order", "desc"))); + bool.put("filter", range); + + search.put("sort", sort); + search.put("query", getJSONObject("bool", bool)); + return setPage(pageIndex, pageSize, search); + } + + + /** + * ES查询 + * + * @param search + * @return + */ + public JsonNode esSearch(JSONObject search, String endpoint, RestClient restClient) { + JsonNode responseNode = null; + try { + logger.info("查询es语句为 {}, endpoint 为:{}", search, endpoint.toString()); + + Request request = new Request(HttpGet.METHOD_NAME, endpoint); + if (search != null) { + String data = search.toString(); + request.setJsonEntity(data); + } + try { + restClient.performRequest(request); + } catch (IOException e) { + logger.error("查询es语句报错为 {}", e.getMessage()); + } + Response response = restClient.performRequest(request); + String responseStr = EntityUtils.toString(response.getEntity()); + logger.info("查询结果为", responseStr); + responseNode = mapper.readTree(responseStr); + } catch (IOException e) { + logger.error("查询失败", e); + } + return responseNode; + } + + + /** + * 设置页面 + * + * @param pageIndex + * @param pageSize + * @param search + * @return + */ + public static JSONObject setPage(Integer pageIndex, Integer pageSize, JSONObject search) { + search.put("from", (pageIndex - 1) * pageSize); + search.put("size", pageSize); + return search; + } + + + /** + * 获取json 对象 + * + * @param key + * @param value + * @return + */ + public static JSONObject getJSONObject(String key, Object value) { + JSONObject term = new JSONObject(); + term.put(key, value); + return term; + } } \ No newline at end of file diff --git a/springboot-elasticsearch/src/main/resources/local/application.properties b/springboot-elasticsearch/src/main/resources/local/application.properties index 5808183..0186699 100644 --- a/springboot-elasticsearch/src/main/resources/local/application.properties +++ b/springboot-elasticsearch/src/main/resources/local/application.properties @@ -60,4 +60,11 @@ pagehelper.params=count=countSql elasticsearch.userName= elasticsearch.password= elasticsearch.rest.hostNames=127.0.0.1 -elasticsearch.rest.port=9200 \ No newline at end of file +elasticsearch.rest.port=9200 + + +#es2\u670D\u52A1\u5668\u5730\u5740\u914D\u7F6E +elasticsearch2.userName= +elasticsearch2.password= +elasticsearch2.rest.hostNames=127.0.0.1 +elasticsearch2.rest.port=9200 \ No newline at end of file