这边没有提供安装es的流程,网上能够找一下。在个人csdn上早就有这篇文章了,我如今搬过来作了一些修改,这边的文章较为彻底,其中贴的代码,大部分不是项目中的,是我练习时的代码,少部分是贴的项目中的。若是要看此文章,仍是要建议要达到本身练习过原生语法,本身能够搭建一个kibana去练习。新手的话,能够去看看狂神的视频,我的以为能够的。公司项目中须要用到es,当时没用过,直接上手了es 的最新版。而后发现项目中springboot版本比较低,常常报错,而后又小小的学习了一下,新版的es相比较旧版(目前用的包 6.4的clint)的话,有些参数必需要。其中_type 这个参数必需要的,可是我感受用处也不是很大。欢迎指定,一块儿学习!javascript
这里只贴了我在项目中封装的crud,这是最开始封装的,并无很完美,但足以拿去直接使用。后续想改,但要动不少,就暂时没改。前端
@Slf4j
public class EsSearchUtils {
private static RestHighLevelClient restHighLevelClient = SpringUtils.getBean(RestHighLevelClient.class);
// 用于查询全部根节点
@Getter
private static List<Integer> proTypeIdList = new ArrayList<>();
/** * es添加的方法 * * @return */
public static <T> boolean add(String indexName, T entity) {
IndexRequest indexRequest = new IndexRequest(indexName);
indexRequest.type("_doc");
indexRequest.source(JSON.toJSONString(entity), XContentType.JSON);
// indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
// indexRequest.setRefreshPolicy("1s");
// WriteRequest.RefreshPolicy refreshPolicy = indexRequest.getRefreshPolicy();
// String value = refreshPolicy.getValue();
// System.out.println("添加是否开启了不延迟:"+value);
try {
restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * es更新的方法 * * @return */
public static <T> boolean update(String indexName, T entity, String _id) {
UpdateRequest updateRequest = new UpdateRequest(indexName, "_doc", _id);
updateRequest.doc(JSON.toJSONString(entity), XContentType.JSON);
// updateRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
try {
restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * es删除的方法 * * @return */
public static boolean delete(String indexName, String _id) {
DeleteRequest deleteRequest = new DeleteRequest(indexName, "_doc", _id);
// deleteRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
try {
restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/** * 封装es查询 操做 * * @param queryBuilder * @param searchRequest * @param sortName 须要排序的字段名 默认降序 * @param page 第几页 * @param pageSize 每页的条数 */
public static List<Map<String, Object>> searchList(QueryBuilder queryBuilder, String[] searchArray, SearchRequest searchRequest, String sortName, Integer page, Integer pageSize) {
//构建构造者
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.timeout(TimeValue.timeValueMillis(2000));
// 限制字段(前者是你想要什么字段,后者是排除什么字段)
if (null != searchArray) {
// searchSourceBuilder.fetchSource(searchArray, new String[]{});
searchSourceBuilder.fetchSource(searchArray, null);
}
// 分页条件
if (!"".equals(page) && null != page) {
if (page < 0) {
page = 0;
}
searchSourceBuilder.from(page);
}
// 分页条件
if (!"".equals(pageSize) && null != pageSize) {
if (pageSize <= 0) {
pageSize = 1;
}
searchSourceBuilder.size(pageSize);
} else {
// 目前设置1万条
searchSourceBuilder.size(10000);
}
// 排序条件
if (!"".equals(sortName) && null != sortName) {
searchSourceBuilder.sort(sortName, SortOrder.DESC);
}
// 查询条件
if (null != queryBuilder) {
searchSourceBuilder.query(queryBuilder);
}
//这里是针对关键字高亮。其实就是将前端代码放在了这里
//searchSourceBuilder.highlighter().preTags("<p class='one' style='color:red'>").postTags("</p>").field("content");
SearchRequest source = searchRequest.source(searchSourceBuilder);
SearchResponse search = null;
try {
search = restHighLevelClient.search(source, RequestOptions.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
search = null;
log.info("============查询出现异常=========");
}
List<Map<String, Object>> list = new ArrayList<>();
if (null != search) {
for (SearchHit hit : search.getHits().getHits()) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
sourceAsMap.put("_id", hit.getId());
sourceAsMap.put("_score", hit.getScore());
list.add(sourceAsMap);
}
}
return list;
}
}
复制代码
直接上手api吧,ElasticSearchCommon 是本身将全部的索引名字封装出来的,这里是只须要一个字符串的! 提早准备的话:导入springboot封装事后的es(也能够不用这样)依赖。而后写一下配置类,配置类我贴出来,再注入一下java
依赖
spring
<!-- elasticsearchs -->
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
复制代码
配置类
sql
@Configuration
public class ElasticSearchConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost(ip,端口,"http")
)
);
return client;
}
}
复制代码
哪些地方要使用就把RestHighLevelClient注入过来
api
@Autowired
// 1.指定方法名
@Qualifier("restHighLevelClient")
private RestHighLevelClient restHighLevelClient;
复制代码
// 建立索引请求
CreateIndexRequest createIndex = new CreateIndexRequest(ElasticSearchCommon.LG_SESSION);
// 客户端执行请求
CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndex, RequestOptions.DEFAULT);
复制代码
DeleteIndexRequest deletRequest = new DeleteIndexRequest(ElasticSearchCommon.LG_SESSION);
AcknowledgedResponse delete = restHighLevelClient.indices().delete(deletRequest, RequestOptions.DEFAULT);
复制代码
GetIndexRequest getIndexRequest = new GetIndexRequest(ElasticSearchCommon.LG_SESSION);
boolean exists = restHighLevelClient.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
复制代码
IndexRequest indexRequest = new IndexRequest(ElasticSearchCommon.LG_SESSION);
// 版本低一点的话须要加上type类型
indexRequest.type("本身定义的类型");
SessionEntity sessionEntity = new SessionEntity();
sessionEntity.setId(1);
sessionEntity.setConversationTime(getNowTime());
sessionEntity.setMsgState(1);
sessionEntity.setAddrImages("/addr/images");
sessionEntity.setVipId("VIP545465");
sessionEntity.setCustomerServerName("弟弟1号");
IndexRequest source = indexRequest.source(JSON.toJSONString(sessionEntity), XContentType.JSON);
IndexResponse index = restHighLevelClient.index(source, RequestOptions.DEFAULT);
System.out.println("预留内容添加状态:"+index.status());
复制代码
// 建立请求
BulkRequest bulkRequest = new BulkRequest(ElasticSearchCommon.LG_SESSION);
// 建立批量数据
List<ProblemTypeEntity> list = new ArrayList<ProblemTypeEntity>();
list.add(new ProblemTypeEntity(1,"111"));
list.add(new ProblemTypeEntity(2,"222"));
list.add(new ProblemTypeEntity(3,"333"));
list.add(new ProblemTypeEntity(4,"444"));
list.add(new ProblemTypeEntity(5,"555"));
list.add(new ProblemTypeEntity(6,"666"));
list.add(new ProblemTypeEntity(7,"777"));
list.add(new ProblemTypeEntity(8,"888"));
// 循环添加
for (int i = 0;i<list.size();i++){
bulkRequest.add(
new IndexRequest(ElasticSearchCommon.LG_SESSION)
//.id(""+(i+1)) // 设置es 当中_id,不设置的话是一串字符
.source(JSON.toJSONString(list.get(i)),XContentType.JSON)
);
}
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println("循环添加的数据状态:"+bulk.status());
复制代码
7.10版能够这样写,根据其余字段条件去查询删除,较新版本的删除这我以为是最方便的springboot
DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(ElasticSearchCommon.LG_PROBLEM);
DeleteByQueryRequest deleteByQueryRequest1 = deleteByQueryRequest.setQuery(QueryBuilders.termQuery("id", 12));
BulkByScrollResponse bulkByScrollResponse = restHighLevelClient.deleteByQuery(deleteByQueryRequest1, RequestOptions.DEFAULT);
System.out.println("删除了几条:"+bulkByScrollResponse.getStatus().getDeleted());
复制代码
老一点的版本,就必须带上_type,我全部的都叫_type,目前没感受到用处,目前探索到,删除只能更具_id 去查询markdown
DeleteRequest deleteRequest = new DeleteRequest(ElasticSearchCommon.LG_PROBLEM,"_doc","_id的值");
DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
复制代码
//第一种写法
// 建立请求
UpdateRequest updateRequest = new UpdateRequest(ElasticSearchCommon.LG_SESSION,"这里就是_id了");
// 建立须要更改的数据
UserEntity userEntity = new UserEntity("更改后的数据",28, CommonUtils.getTimeFormat());
// 修改的数据放入请求中
updateRequest.doc(JSON.toJSONString(userEntity),XContentType.JSON);
// 客户端发送请求
UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
// 打印状态
System.out.println("更新状态:"+update.status());
复制代码
你要去了解QueryBuilders里面的一些方法。session
*QueryBuilders.termQuery("key", obj) 彻底匹配,输入的查询内容是什么,就会按照什么去查询,并不会解析查询内容,对它分词。
*QueryBuilders.termsQuery("key", obj1, obj2..) 一次匹配多个值
*QueryBuilders. matchQuery("key", Obj) 单个匹配,match查询,会将搜索词分词,再与目标查询字段进行匹配,若分词中的任意一个词与目标字段匹配上,则可查询到。
*QueryBuilders. multiMatchQuery("text", "field1", "field2"..); 匹配多个字段, field有通配符忒行
*QueryBuilders. matchAllQuery(); 匹配全部文件
*QueryBuilders.matchPhraseQuery(“supplierName”,param);默认使用 match_phrase 时会精确匹配查询的短语,须要所有单词和顺序要彻底同样,标点符号除外
*QueryBuilders.wildcardQuery(“supplierName”,"*"+param+"*") ;条件wildcard不分词查询,加*(至关于sql中的%)表示模糊查询,加keyword表示查不分词数据
复制代码
builderList 我本身写的操做es库的一个方法;这里和上面在项目中使用的封装大体同样,这里名字换了一下,这个就作参考就好了,要在项目中使用的话,就用上面的 随机一个方法:elasticsearch
SearchRequest searchRequest = new SearchRequest(ElasticSearchConstant.LG_PROBLEM);
MatchQueryBuilder should = QueryBuilders.matchQuery("content", content).operator(Operator.OR);
List<Map<String, Object>> list = builderList(should, searchRequest,null,0,5);
HashMap<String,Object> hashMap = new HashMap<String, Object>();
// 分词未搜到则 返回热度最高的5个数据
if (list.size() <= 0){
List<Map<String, Object>> heatList = MostHeat();
hashMap.put("heat","未查询到关键词,返回热度最高的五个问题!");
heatList.add(0,hashMap);
return heatList;
}
复制代码
builderList方法:封装的查询 //构建构造者
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.timeout(TimeValue.timeValueMillis(1));
// 分页条件
if (!"".equals(page) && null != page){
if (page < 0 ){
page = 0;
}
searchSourceBuilder.from(page);
}
// 分页条件
if (!"".equals(pageSize) && null != pageSize){
if (pageSize <= 0 ){
pageSize = 1;
}
searchSourceBuilder.size(pageSize);
}
// 排序条件
if (!"".equals(sortName) && null != sortName){
searchSourceBuilder.sort(sortName, SortOrder.DESC);
}
// 查询条件
if (null != queryBuilder ){
searchSourceBuilder.query(queryBuilder);
}
//searchSourceBuilder.highlighter().preTags("<p class='one' style='color:red'>").postTags("</p>").field("content");
SearchRequest source = searchRequest.source(searchSourceBuilder);
SearchResponse search = restHighLevelClient.search(source, RequestOptions.DEFAULT);
List<Map<String,Object>> list = new ArrayList<>();
for (SearchHit hit : search.getHits().getHits()) {
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
sourceAsMap.put("_id",hit.getId());
//sourceAsMap.remove("addrImages");
list.add(sourceAsMap);
}
复制代码
customerName.keyword 表明不分词搜索,总体搜索,彻底匹配 query.term,以前网上也是说不分词搜索,欢迎大佬指定
仍是得本身去摸索着玩吧,这样踩几个坑就知道了,后续会更新其余的。最重要就多在查询上面花点心思,还有不少查询未摸索到。这里没写到ik,但项目中是使用到了的。es注意的地方,他的全部增删改都不是及时的去刷新索引中的信息的,网上有不少说在3s 有的说在1s,我这边感受大体是1s。能够经过参数去把延迟刷新去除,若是频繁的操做容易破坏索引和其余缘由,暂时还不太清楚。