ElasticSearch是一个分布式、RESTful风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为ES的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。
-
分布式
-
集群:同一个业务拓展到很多份
- 为了增加并发性;集群一定会有负载均衡的前置
-
分布式:
- 微服务
- 不同业务部署到不同地方
-
-
分布式一定是集群,集群不一定是分布式
- 高并发、高可用
- 我们代码也需要并发优化
-
RESTful风格
-
所有功能暴露为HTTP请求方式
-
天然优势?
- 跨任意语言平台兼容性强 (可以实现多语言兼容,只要发送HTTP请求即可)
-
搜索和数据分析引擎
- ES默认存在内存中
- ES用来搜索个分析。MySQL是为了数据存档(持久化)
- MySQL存储结构化数据(数据模型固定,基本不会修改)
- ES可以存储非结构化数据(数据模型不固定)
-
springboot 配置es @Configuration public class ElasticSearchConfig {
/**
* 防止netty的bug
* java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]
*/
@PostConstruct
void init() {
System.setProperty("es.set.netty.runtime.available.processors", "false");
}
}
连接es服务器
@Configuration
@Slf4j
public class EsConfig {
@Bean
RestHighLevelClient restHighLevelClient(@Value("${spring.elasticsearch.hosts}") String hosts) {
String[] hostsWithPort = hosts.split(",");
HttpHost[] httpHosts = new HttpHost[hostsWithPort.length];
for (int i = 0; i < hostsWithPort.length; i++) {
String hostWithPort = hostsWithPort[i];
String[] hostPort = hostWithPort.split(":");
String host = hostPort[0];
String port = hostPort[1];
httpHosts[i] = new HttpHost(host, Integer.parseInt(port));
}
return new RestHighLevelClient(RestClient.builder(httpHosts));
}
在代码中引入
@Autowired
RestHighLevelClient restHighLevelClient;
添加数据操作
public boolean create(@RequestBody SpecialPersonnelAlarm specialPersonnelAlarm) throws Exception {
//将对象转化为Json串,可以自定义一些转化规则
String jsonParam = JSONObject.toJSONString(specialPersonnelAlarm,
SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);
//实体类的id。
return create(EventConfigKey.INDEX, EventConfigKey.INDEX_TYPE, specialPersonnelAlarm.getId().toString(), jsonParam);
}
//传入索引、类型、id和json字符串进行新增操作
public boolean create(String index, String type, String id, String jsonParam) throws Exception {
//创建添加数据请求
IndexRequest indexRequest = new IndexRequest(index, type, id).source(jsonParam, XContentType.JSON);
try {
//执行索引请求
IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
if (response.status().getStatus() == 201) {
return true;
}
} catch (IOException e) {
throw new Exception("restClient.create.error");
}
return false;
}
查询数据
public ResponseResult<List> selectRegulatoryWarning(@ApiParam(value = "人员类型") @RequestParam(required = false) String type,
@ApiParam(value = "日期") @RequestParam(required = false) Date statisticDate) throws IOException {
//获取年月日
String yearMonthDayString = DateStringUtils.getYearMonthDayString(statisticDate);
SearchRequest searchRequest = new SearchRequest(EventConfigKey.INDEX);
searchRequest.types(EventConfigKey.INDEX_TYPE);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//精确查询and
if(type!=null&& !type.equals("")){
QueryBuilder queryBuilder1 = QueryBuilders.termQuery("type", type);
boolQueryBuilder.must(queryBuilder1);
}
QueryBuilder queryBuilder = QueryBuilders.wildcardQuery("statisticDate",yearMonthDayString+"*");
boolQueryBuilder.must(queryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
//根据某个字段排序
searchSourceBuilder.sort("statisticDate", SortOrder.DESC);
//将所有的条件进行整合
searchRequest.source(searchSourceBuilder);
//根据restHighLevelClient进行查询
SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
SearchHits searchHits = search.getHits();
SearchHit[] hits = searchHits.getHits();
List list=new ArrayList();
//获取到实体中的内容
for (SearchHit hit:hits){
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
sourceAsMap.put("type",specialPersonnelInfoMapper.findConfigName(EventConfigKey.SPEACIAL_PERSONNEL_TYPE,sourceAsMap.get("type").toString()));
sourceAsMap.put("state",specialPersonnelInfoMapper.findConfigName(EventConfigKey.SPEACIAL_PERSONNEL_STATE,sourceAsMap.get("state").toString()));
list.add(sourceAsMap);
}
return ResponseResult.ok(list);
}
yml文件配置
spring:
elasticsearch:
hosts: ip:9200
自动创建索引
@Autowired
RestHighLevelClient restHighLevelClient;
@PostConstruct
public boolean createIndex() throws IOException {
String indexName="索引名称";
GetIndexRequest getIndexRequestrequestTablename = new GetIndexRequest(indexName);
boolean existsTablename = restHighLevelClient.indices().exists(getIndexRequestrequestTablename, RequestOptions.DEFAULT);
if (!existsTablename) {
org.elasticsearch.action.admin.indices.create.CreateIndexRequest request = new org.elasticsearch.action.admin.indices.create.CreateIndexRequest(indexName);
request.settings(Settings.builder()
// 设置分片数为3, 副本为2
.put("index.number_of_shards", 3)
.put("index.number_of_replicas", 2)
);
// 这里创建索引结构
CreateIndexRequest mapping = request.mapping("type类型名称", generateBuilder());
CreateIndexResponse response = restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
// 指示是否所有节点都已确认请求
boolean acknowledged = response.isAcknowledged();
// 指示是否在超时之前为索引中的每个分片启动了必需的分片副本数
boolean shardsAcknowledged = response.isShardsAcknowledged();
if (acknowledged || shardsAcknowledged) {
System.out.println("创建索引成功!索引名称为{}" + indexName);
return true;
}
}else {
System.out.println("索引已存在");
return false;
}
return existsTablename;
}
private XContentBuilder generateBuilder() throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.startObject("properties");
{
builder.startObject("id");
{
builder.field("type", "integer");
}
builder.endObject();
}
{
builder.startObject("addTime");
{
builder.field("type", "date");
builder.field("format","yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
}
builder.endObject();
}
{
builder.startObject("updateTime");
{
builder.field("type", "date");
builder.field("format","yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis");
}
builder.endObject();
}
builder.endObject();
}
builder.endObject();
return builder;
}
pom文件配置
<dependency>
<!-- ElasticSearch-->
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.1.0</version>
<exclusions>
<exclusion>
<artifactId>elasticsearch</artifactId>
<groupId>org.elasticsearch</groupId>
</exclusion>
<exclusion>
<artifactId>elasticsearch-rest-client</artifactId>
<groupId>org.elasticsearch.client</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>7.1.0</version>
</dependency>
启动类添加
public static void main(String[] args){
System.setProperty("es.set.netty.runtime.available.processors", "false");
SpringApplication.run(EventServiceApp.class, args);
}