ES客户端操作 ---Apollo配置中心
1.引入jar包
<!-- es -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>5.6.4</version>
</dependency>
<!-- transport客户端 -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.6.4</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.13.Final</version>
</dependency>
2.Apollo上部署
<!-- es -->
<bean class="........EsBuildersServiceUtil">
<property name="clusterName" value="${es.cluster.name}"></property>
<property name="hosts" value="${es.hosts}"></property>
</bean>
<apollo:config namespaces="......, es, ........" />
EsBuildersServiceUtil的API 略
public class EsBuildersServiceUtil {
private final Logger logger = LoggerFactory.getLogger(EsBuildersServiceUtil.class);
/**es客户端*/
private static volatile Client client;
/**集群名称*/
private static String clusterName;
/**
* 配置中心配置的为ip:port
*/
private static String hosts;
/**用volatile和synchronized来满足双重检查锁机制------- 单例模式*/
public static Client getESClient() {
if (client != null) {
return client;
}
synchronized (EsBuildersServiceUtil.class) {
if (client == null) {
System.setProperty("es.set.netty.runtime.available.processors", "false");
Settings settings = Settings.builder().put("cluster.name", clusterName).build();
try {
TransportClient transportClient = new PreBuiltTransportClient(settings);
String[] hostsArr = hosts.split(",");
for (String s : hostsArr) {
String[] ipPort = s.split(":");
client = transportClient.addTransportAddress(new InetSocketTransportAddress(
InetAddress.getByName(ipPort[0]), Integer.parseInt(ipPort[1])));
}
} catch (UnknownHostException e) {
throw new RuntimeException("init elasticsearch client UnknownHostException", e);
} catch (Exception e) {
throw new RuntimeException("init elasticsearch client exception", e);
}
}
}
return client;
}
分页查询es的数据
一开始使用了from+size分页查询,但未注意到这种方式的两个缺点
1)每次查询都从第一条开始查询,所以分页的偏移值越大,执行分页查询时间就会越长。
2)查询默认不能超过一万条,因为size的大小不能超过index.max_result_window这个参数的设置,默认就是10000
PUT _settings
{
"index": {
"max_result_window": "10000000"
}
}
最终我使用了scroll分页方式,如果数据量很大的情况下使用上性能更好,但是也有不灵活和加大内存,消耗CPU等缺点
from+size常规查询
部分代码 如下:
@Service
public class MembershipDataCardInfoServiceImpl {
public MembershipDataCardInfoResponse queryWidFromES(MembershipDataCardInfoRequest membershipCardInfoRequest) {
try {
/* 组装参数 */
QueryBuilder builder = getMembershipCardInfo(membershipCardInfoRequest);
/* 分页查询es */
SearchResponse searchResponse = EsBuildersServiceUtil.queryWithPage(
MembershipDataConstant.ES_INDEX_NAME_MEMBERCARD, MembershipDataConstant.ES_TYPE_NAME_MEMBERCARD,
builder, (membershipCardInfoRequest.getPageNo() - 1) * membershipCardInfoRequest.getPageSize(),
membershipCardInfoRequest.getPageSize());
SearchHits hits = searchResponse.getHits();
List<MembershipCardInfoVo> membershipCardInfoVos = new ArrayList<>();
if (hits.getTotalHits() > 0) {
for (SearchHit hit : hits.getHits()) {
if (null != hit.getSource() && null != hit.getSource().get(MembershipDataConstant.ES_RETURN_FIELD)
&& null != hit.getSource().get(MembershipDataConstant.ES_RETURN_FIELD_PID)) {
membershipCardInfoVo = new MembershipCardInfoVo();
membershipCardInfoVo.setPid(Long.parseLong(hit.getSource()
.get(MembershipDataConstant.ES_RETURN_FIELD_PID).toString()));
membershipCardInfoVos.add(membershipCardInfoVo);
}
}
}
membershipCardInfoResponse.setMembershipCardInfoVos(membershipCardInfoVos);
return membershipCardInfoResponse;
} catch (Exception e) {
throw new MembershipDataException(MembershipDataErrorCode.ES_CARD_INFO_ERROR);
}
}
public QueryBuilder getMembershipCardInfo(MembershipDataCardInfoRequest membershipCardInfoRequest) {
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("pid", membershipCardInfoRequest.getPid()));
boolQueryBuilder.must(
QueryBuilders.termQuery("memberCardTemplateId", membershipCardInfoRequest.getMemberCardTemplateId()));
return boolQueryBuilder;
}
}
scroll深查询 以scrollId为游标,记录查询位置
部分代码如下:
public MembershipDataCardInfoResponse queryWidScrollFromES(MembershipDataCardInfoRequest param, Client client) {
MembershipDataCardInfoResponse dataCardInfoResponse=null;
SearchResponse response=null;
try {
/* 1.组装参数 */
QueryBuilder builder = getMembershipCardInfo(param);
if(param.getScrollId()==null) {
/*2.无scrollId,第一次查询*/
response = client.prepareSearch(MembershipDataConstant.ES_INDEX_NAME_MEMBERCARD)
.setTypes(MembershipDataConstant.ES_TYPE_NAME_MEMBERCARD)
.setQuery(builder)
.setSize(param.getPageSize())
.setScroll(new TimeValue(scrollTime)).execute().actionGet();
}else{
/*3.带scrollId查询*/
response = client.prepareSearchScroll(param.getScrollId())
.setScroll(new TimeValue(scrollTime)).execute().actionGet();
}
dataCardInfoResponse=searchScrollWid(response);
} catch (Exception e) {
throw new MembershipDataException(MembershipDataErrorCode.ES_CARD_INFO_ERROR);
}
return dataCardInfoResponse;
}
在客户端操作ES
创建索引
http://localhost:9200/test_data_userinfo/
{
"settings": {
"number_of_shards": "5",
"number_of_replicas": "1"
},
"mappings": {
"novel": {
"properties": {
"name": {
"type": "text"
},
"author": {
"type": "keyword"
},
"word_count": {
"type": "integer"
},
"publish_date": {
"type": "date"
}
}
}
}
}
插入
指定id插入数据
PUT 路径是:服务ip:端口/索引名/类型名/id
http://localhost:9200/test_data_userinfo/novel/insert_3/
{
"name": "神雕侠侣",
"author": "金庸",
"word_count": "88888888",
"publish_date": "2019-04-17"
}
不指定id插入数据
POST 路径是:服务ip:端口/索引名/类型名/ 不能指定id,插入成功后会返回id
http://localhost:9200/test_data_userinfo/novel/
{
"name": "红楼梦",
"author": "曹雪芹",
"word_count": "88888888",
"publish_date":"2019-04-17"
}
修改
POST 路径为:服务ip:端口/索引名/类型名/要修改的数据的id/
http://localhost:9200/test_data_userinfo/novel/insert_1/
{
"name": "红楼梦",
"author": "曹雪芹",
"word_count": "88888888",
"publish_date": "2019-04-17"
}
删除
DELETE 直接使用delete请求,指定索引,类型,id即可删除
http://localhost:9200/test_data_userinfo/novel/insert_1/
网友评论