IK 分词器插件
IK 分词器可以对中文进行一个分词操作的插件。即把一段中文或者别的划分成一个个的关键字,在搜索的时候会将搜索关键词进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词(不使用用IK分词器的情况下)。
IK 分词器默认提供了两个分词算法:(ik_smart 和 ik_max_word),其中 ik_smart 为最少切分,ik_max_word 为最细粒度划分!
下载
- 下载:Github 下载地址:https://github.com/medcl/elasticsearch-analysis-ik
- 下载完毕之后,放入到 Elasticsearch 的 plugins 目录下即可。
- 重启 Elasticsearch,可以看到 ik 插件被加载。
- 在 Kibana 中进行测试
GET_analyze{ "analyzer": "ik_smart", "text": "蜘蛛侠"} GET_analyze{ "analyzer": "ik_max_word", "text": "蜘蛛侠"}
自定义词典
在 IK 的 config 的目录中创建自定义文件 my.dic
添加文本,保存退出。
在 IKAnalyzer.cfg.xml 中配置自己的扩展字典。
重启 ES,
访问 Kibana 可以查看 “蜘蛛侠” 被分为一个词。
如果我们需要自定义分词即在 dic 文件中进行配置即可。
Rest 风格说明
Rest 风格是一种软件架构风格,不是一种标准,它只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
字段数据类型
主要字段类型如下:
- 字符串类型:text、keyword
- text:支持分词,全文检索,支持模糊、精确查询,不支持聚合,排序操作;text类型的最大支持的字符长度无限制,适合大字段存储;
- keyword:不进行分词,直接索引、支持模糊、支持精确匹配,支持聚合、排序操作。keyword类型的最大支持的长度为——32766个 UTF-8 类型的字符,可以通过设置 ignore_above 指定自持字符长度,超过给定长度后的数据将不被索引,无法通过 term 精确匹配检索返回结果。
- 数值型:long、Integer、short、byte、double、float、half float、scaled float
- 日期类型:date
- 布尔类型:boolean
- 二进制类型:binary
注:如果自己的文档字段没有指定,那么es就会给我们默认配置字段类型!
基本命令
method | url地址 | 描述 |
PUT(创建,修改) | localhost:9200/索引名称/类型名称/文档id | 创建文档(指定文档id) |
POST(创建) | localhost:9200/索引名称/类型名称 | 创建文档(随机文档id) |
POST(修改) | localhost:9200/索引名称/类型名称/文档id/_update | 修改文档 |
DELETE(删除) | localhost:9200/索引名称/类型名称/文档id | 删除文档 |
GET(查询) | localhost:9200/索引名称/类型名称/文档id | 查询文档通过文档ID |
POST(查询) | localhost:9200/索引名称/类型名称/文档id/_search | 查询所有数据 |
样例:创建索引
PUT /索引名/~类型名~/文档id {请求体}
PUT /test1/type1/1 { "name": "蜘蛛侠", "age": 21 }
即创建一个索引 test1 ,文档类型名为 type1,文档 id 为 1。
通过 ES Head 查看数据
高亮显示
GET test/user/_search { "query": { //搜索匹配 name 包含"侠" "match": { "name": "侠" } }, "highlight": { //高亮 "pre_tags": "<font color='red'>", //html 前缀 "post_tags": "</font>", //html 后缀 "fields": { //属性 "name": {} } } }
集成 SpringBoot
官方文档
- 点击链接进入官网:https://www.elastic.co/cn/,点击学习下面的文档。
- 找到并点击 Elasticsearch Clients
- 这里就是官方支持的文档了
测试 API
创建项目和 ES 配置类
- 新建 一个SpringBoot 项目,导入 Elasticsearch 和 fastjson 依赖。
- 编写 ElasticSearchClientConfig 配置类。
@Configuration public class ElasticSearchClientConfig { //RestHighLevelClient对象 @Bean public RestHighLevelClient restHighLevelClient(){ RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( //集群设置多个 new HttpHost("127.0.0.1", 9200, "http"))); return client; } }
- 测试类中注入 RestHighLevelClient 对象。
@Autowired @Qualifier("restHighLevelClient") private RestHighLevelClient client;
创建索引
//创建索引voidcreateIndex() throwsIOException { CreateIndexRequestrequest=newCreateIndexRequest("spring_test"); CreateIndexResponsecreateIndexResponse=client.indices().create(request, RequestOptions.DEFAULT); System.out.println(createIndexResponse); }
判断索引是否存在
//判断索引是否存在,存在返回 true,不存在 falsevoidisExistIndex() throwsIOException { GetIndexRequestrequest=newGetIndexRequest("spring_test"); booleanexists=client.indices().exists(request, RequestOptions.DEFAULT); System.out.println(exists); }
删除索引
//删除索引,删除成功,response.isAcknowledged()=true,否则为 falsevoiddeleteIndex() throwsIOException { DeleteIndexRequestrequest=newDeleteIndexRequest("spring_test"); AcknowledgedResponseresponse=client.indices().delete(request, RequestOptions.DEFAULT); System.out.println(response.isAcknowledged()); }
添加文档
//测试添加文档(User 对象)voidaddDoc() throwsIOException { //创建对象Useruser=newUser("Jie", 20); //创建请求IndexRequestrequest=newIndexRequest("spring_test"); //创建规则request.id("1"); request.timeout(TimeValue.timeValueSeconds(1)); //将数据 json 格式放入请求request.source(JSON.toJSONString(user), XContentType.JSON); //客户端发送请求,获取响应的结果IndexResponseresponse=client.index(request, RequestOptions.DEFAULT); System.out.println(response); System.out.println(response.status()); }
判断文档是否存在
//判断文档是否存在 get /index/doc/1voidisExistsDoc() throwsIOException { //获取 GetRequest 请求,构造重载 index,type,idGetRequestrequest=newGetRequest("spring_test","1"); //不获取返回的 _source 的上下文request.fetchSourceContext(newFetchSourceContext(false)); request.storedFields("_none_"); booleanexists=client.exists(request, RequestOptions.DEFAULT); System.out.println(exists); }
获取文档信息
voidgetDoc() throwsIOException { //获取 GetRequest 请求,构造重载 index,type,idGetRequestrequest=newGetRequest("spring_test","1"); GetResponseresponse=client.get(request, RequestOptions.DEFAULT); //将文档内容作为字符串输出System.out.println(response.getSourceAsString()); //响应信息是与命令是一样的System.out.println(response); }
更新文档信息
- 获取 UpdateRequest 请求
- 设置数据,将数据转为 JSON 格式。
- 客户端执行请求
//更新文档信息voidupdateDoc() throwsIOException { //获取 GetRequest 请求,构造重载 index,type,idUpdateRequestrequest=newUpdateRequest("spring_test","1"); request.timeout("1s"); //创建对象Useruser=newUser("I'm Jie", 22); //将对象封装为 JSON 类型request.doc(JSON.toJSONString(user),XContentType.JSON); UpdateResponseresponse=client.update(request, RequestOptions.DEFAULT); System.out.println(response); System.out.println(response.status()); }
删除文档信息
- 获取 DeleteRequest 请求
- 客户端执行请求
//删除文档信息voiddelDoc() throwsIOException { //获取 GetRequest 请求,构造重载 index,type,idDeleteRequestrequest=newDeleteRequest("spring_test","1"); request.timeout("1s"); DeleteResponseresponse=client.delete(request, RequestOptions.DEFAULT); System.out.println(response); System.out.println(response.status()); }
批量添加文档信息
- 获取 BulkRequest 请求
- 准备数据
- 批处理请求
- 循环添加请求数据,将数据转为 JSON 格式。
- 客户端执行请求
//批量添加文档信息voidbulkRequest() throwsIOException { BulkRequestrequest=newBulkRequest(); request.timeout("10s"); //准备数据ArrayList<User>users=newArrayList<>(); users.add(newUser("test1",2)); users.add(newUser("test2",3)); users.add(newUser("test3",2)); users.add(newUser("test4",5)); users.add(newUser("test5",2)); //批处理请求for (inti=0; i<users.size(); i++) { request.add( newIndexRequest("spring_test") .id((i+1)+"") //不设置 id,默认随机 id .source(JSON.toJSONString(users.get(i)),XContentType.JSON)); } //提交请求BulkResponseresponse=client.bulk(request, RequestOptions.DEFAULT); System.out.println(response); System.out.println(response.status()); }
查询信息
- 获取 SearchRequest 请求
- 构建搜索条件
- 设置查询条件(通过 SearchSourceBuilder 构造对应的条件)
- 客户端执行请求
- 解析响应结果
//查询//SearchRequest 搜索请求//SearchSourceBuilder 条件构造//使用 QueryBuilders 创造条件//HighlightBuilder 构建高亮//TermQueryBuilder 精确查询//MatchAllQueryBuilder 匹配所有voidsearch() throwsIOException { //请求SearchRequestsearch=newSearchRequest("spring_test"); //构建搜索条件SearchSourceBuildersourceBuilder=newSearchSourceBuilder(); /*查询条件,可以使用 QueryBuilders 工具类实现*/TermQueryBuildertermQueryBuilder=QueryBuilders.termQuery("age", 2); sourceBuilder.query(termQueryBuilder); //设置时间sourceBuilder.timeout(newTimeValue(60, TimeUnit.SECONDS)); search.source(sourceBuilder); SearchResponseresponse=client.search(search, RequestOptions.DEFAULT); System.out.println(response); System.out.println(JSON.toJSONString(response.getHits())); System.out.println("==============================="); for (SearchHithit : response.getHits().getHits()) { System.out.println(hit.getSourceAsMap()); } }
高亮字段
- 获取 SearchRequest 请求
- 设置搜索条件
- 设置查询条件
- 设置高亮
- 执行查询
- 客户端执行请求
- 解析查询结果
- 将高亮字段替换掉原来的字段(查询出来的高亮字段和源字段不是同一个,所以需要用高亮后的字段替换源字段)
//高亮字段voidhighLight() throwsIOException { //请求SearchRequestsearch=newSearchRequest("spring_test"); //构建搜索条件SearchSourceBuildersourceBuilder=newSearchSourceBuilder(); TermQueryBuildertermQueryBuilder=QueryBuilders.termQuery("name", "test1"); sourceBuilder.query(termQueryBuilder); sourceBuilder.timeout(newTimeValue(60, TimeUnit.SECONDS)); //高亮HighlightBuilderhighlightBuilder=newHighlightBuilder(); highlightBuilder.field("name"); //设置高亮字段highlightBuilder.requireFieldMatch(false); //取消多个高亮highlightBuilder.preTags("<font color='red'>"); //前缀highlightBuilder.postTags("</font>"); //后缀sourceBuilder.highlighter(highlightBuilder); //执行搜索search.source(sourceBuilder); SearchResponseresponse=client.search(search, RequestOptions.DEFAULT); //解析结果ArrayList<Map<String,Object>>list=newArrayList<>(); for (SearchHithit : response.getHits().getHits()) { Map<String, HighlightField>highlightFields=hit.getHighlightFields(); HighlightFieldname=highlightFields.get("name"); //获取原理的结果Map<String, Object>sourceAsMap=hit.getSourceAsMap(); // 将高亮字段替换掉原来的字段if(name!=null){ Text[] texts=name.getFragments(); Stringn_name=""; for (Texttext : texts) { n_name+=text; } sourceAsMap.put("name",n_name); } list.add(sourceAsMap); } }