# ik_smart最少切分 GET _analyze { "analyzer": "ik_smart", "text": "河南科技大学" } # ik_max_word 最细粒度划分!穷尽词库所有可能 GET _analyze { "analyzer": "ik_max_word", "text": "河南科技大学" } # ===================ES索引相关的基本操作======================= # 创建索引(数据库) # 索引库名称:csp ,文档类型名称:mytype ,文档id:1 PUT /csp/mytype/1 { "name":"兴趣使然的草帽路飞", "age":"22" } # 创建一个csp2索引库: # 索引库名称:csp2 # 索引库中3个字段:name,age,birthday # 3个字段的类型为:text,integer,date PUT /csp2 { "mappings": { "properties": { "name":{ "type": "text" }, "age":{ "type": "integer" }, "birthday":{ "type": "date" } } } } # 获得索引csp2的相关信息 GET csp2 # 创建索引csp3,文档类型使用默认的_doc,文档id:1 # 数据为:nage,age,birthday PUT /csp3/_doc/1 { "name":"兴趣使然的草帽路飞", "age":22, "birthday":"1999-01-29" } # 查看索引csp3默认的信息 GET csp3 # 查看es健康状态 GET _cat/health # 查看所有索引库简要信息 GET _cat/indices?v # 修改索引csp3数据 # 修改的字段name POST /csp3/_doc/1/_update { "doc":{ "name":"海贼王路飞" } } # 删除csp索引库 DELETE csp # ===================ES文档相关的基本操作======================= # 创建索引my_index,文档类型user,文档id:1 # user:1 PUT /my_index/user/1 { "name":"草帽路飞", "age":22, "description":"海贼王,我当定了!", "tags":["吃货","船长","未来的海贼王","橡胶果实能力者"] } # user:2 PUT /my_index/user/4 { "name":"海贼猎人索隆1", "age":22, "description":"背后的伤疤,是剑士的耻辱!", "tags":["路痴","副船长","未来的世界第一大剑豪","三刀流剑客"] } PUT /my_index/user/5 { "name":"海贼猎人索隆2", "age":25, "description":"背后的伤疤,是剑士的耻辱!", "tags":["路痴","副船长","未来的世界第一大剑豪","三刀流剑客"] } PUT /my_index/user/2 { "name":"海贼猎人索隆3", "age":24, "description":"背后的伤疤,是剑士的耻辱!", "tags":["路痴","副船长","未来的世界第一大剑豪","三刀流剑客"] } # user:3 PUT /my_index/user/3 { "name":"黑足山治", "age":22, "description":"为了天下女性而活!", "tags":["色胚","厨师","未来海贼王船上的初始","踢技炫酷"] } # 获取数据 # 获取user:1 GET /my_index/user/1 # 搜索数据 GET /my_index/user/_search?q=name:路飞 # 搜索数据,通过json构建查询参数 # 搜索得到的结果中: # hits: 表示索引和文档相关信息 # "total": # "value": 查询到的结果的总记录数 # "relation": 搜索结果和搜索参数的关系:eq表示相等 lt小于 gt大于 # "_index": 表示索引名称 # "_tyoe": 表示文档类型 # "_id": 表示文档id # "_score": 表示搜索结果的权重 # "_source": 表示文档中的数据 # 文档中数据的字段名称以及值 GET /my_index/user/_search { "query": { "match": { "name": "索隆" } } } # 搜索数据,通过json构建查询参数,加上结果过滤 # query:构建要搜索的条件,match:构建要匹配的内容 # _source: 结果过滤,只获取name和age字段数据 # sort: 排序条件 age:要排序的字段 order:desc 降序 # from:从第几条数据开始0表示第一条,size:每页显示几条数据 GET /my_index/user/_search { "query": { "match": { "name": "索隆" } }, "_source": ["name","age"], "sort": [ { "age": { "order": "desc" } } ], "from": 0, "size": 1 } # 搜索数据:使用bool多条件精确查询 # 查询22岁的所有用户,且名字中带有索隆的 # bool: 多条件精确查询 # must: [] 数组中的所有条件都需要符合 === 且and的关系 GET /my_index/user/_search { "query": { "bool": { "must": [ { "match": { "age": "22" } }, { "match": { "name": "索隆" } } ] } } } # 搜索数据:使用bool多条件精确查询 # 查询22岁的所有用户,或者名字中带有索隆的所有用户 # bool: 多条件精确查询 # shoud: [] 数组中的所有条件只要有一个符合就行 === 或or的关系 GET /my_index/user/_search { "query": { "bool": { "should": [ { "match": { "age": "22" } }, { "match": { "name": "索隆" } } ] } } } # 搜索数据:使用bool多条件精确查询,filter过滤 # 查询所有用户,名字中有索隆的,且年龄在22-25之间 # bool: 多条件精确查询,filter:按照字段过滤 === gt lt eq gte大于等于 lte 小于等于 GET /my_index/user/_search { "query": { "bool": { "must": [ { "match": { "name": "索隆" } } ], "filter": { "range": { "age": { "lt": 22, "gt": 25 } } } } } } # 根据tags数组中的内容搜索,以空格分割查询条件 # 结果:可以得到路飞和山治的信息 GET /my_index/user/_search { "query": { "match": { "tags": "厨师 船长" } } } # 精确查询: # term: 精确查询,直接通过倒排索引指定的词条进行精确查找 # match: 会使用分词器解析(先分析文档,然后再通过分析的文档进行查询) # 两个类型: text 和 keyword # 新建一个索引 PUT my_index2 { "mappings": { "properties": { "name":{ "type": "text" }, "description":{ "type": "keyword" } } } } # 向my_index2插入数据 PUT /my_index2/_doc/1 { "name":"蒙奇D路飞", "description":"海贼王我当定了!" } # 使用分词器查询 # "analyzer": "keyword" 使用ik分词器查询 GET _analyze { "analyzer": "keyword", "text": "海贼王我当定了!" } # 使用分词器查询 # "analyzer": "standard" 使用默认分词器查询 # 该分词器会逐个拆分每个词(字) GET _analyze { "analyzer": "standard", "text": "海贼王我当定了!" } # term 精确查询 # 由结果得出: # keyword类型(description)的字段不会被分词器解析 # text类型(name)的字段会被分词器解析 GET /my_index2/_search { "query": { "term": { "name": { "value": "路" } } } } # 插入模拟数据 PUT /my_index2/_doc/3 { "t1":"33", "t2":"2020-1-17" } PUT /my_index2/_doc/4 { "t1":"44", "t2":"2020-1-18" } PUT /my_index2/_doc/5 { "t1":"55", "t2":"2020-1-19" } PUT /my_index2/_doc/6 { "t1":"66", "t2":"2020-1-20" } # 精确查询多个值 GET /my_index2/_search { "query": { "bool": { "should": [ { "term": { "t1": { "value": "44" } } }, { "term": { "t1": { "value": "55" } } } ] } } } # (重点)高亮查询: # highlight:搜索结果高亮展示 # fields:对应的字段数组 # pre_tags: 高亮展示结果的标签前缀,默认是<em> # post_tags: 高亮展示结果的标签后缀,默认是</em> GET /my_index/user/_search { "query": { "match": { "name": "索隆" } }, "highlight": { "pre_tags": "<p class='key' style='color:red'>", "post_tags": "</p>", "fields": { "name":{} } } }
SpringBoot整合ES
pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
可以在application.yml中配置,也可以使用下面的方法配置:
ElasticSearchConfig.java
/** * @Auther: csp1999 * @Date: 2020/07/11/15:16 * @Description: ES 客户端配置 */ @Configuration // 相当于xml 配置 bean public class ElasticSearchConfig { // spring <beans id="restHighLevelClient" class="RestHighLevelClient"> @Bean public RestHighLevelClient restHighLevelClient(){ RestHighLevelClient client = new RestHighLevelClient( RestClient.builder( new HttpHost("127.0.0.1", 9200, "http"))); return client; } }
SpringBoot测试类
/** * @Auther: csp1999 * @Date: 2020/07/11/15:16 * @Description: es7.6.x客户端测试 API */ @SpringBootTest class HaustEsApiApplicationTests { @Autowired @Qualifier("restHighLevelClient") private RestHighLevelClient client; /** * 索引的创建 Request: PUT csp_index * * @throws IOException */ @Test void testCreateIndex() throws IOException { // 1.创建索引请求 CreateIndexRequest request = new CreateIndexRequest("csp_index"); // 2.执行创建请求 IndicesClient 请求后获得响应 CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT); // 输出结果 System.out.println(createIndexResponse);// org.elasticsearch.client.indices.CreateIndexResponse@cd831c72 } /** * 获取索引 GET * * @throws IOException */ @Test void testExistIndex() throws IOException { // 1.获取索引库的请求 GetIndexRequest request = new GetIndexRequest("csp_index"); // 2.执行获取索引库的请求 boolean exists = client.indices().exists(request, RequestOptions.DEFAULT); // 输出结果 System.out.println(exists);// 如果索引库存在,则输出:true,否则输出false } /** * 删除索引 DELETE * * @throws IOException */ @Test void testDeleteIndex() throws IOException { // 1.删除索引库的请求 DeleteIndexRequest request = new DeleteIndexRequest("csp_index"); // 2.执行删除索引库的请求 AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT); // 输出结果 System.out.println(delete.isAcknowledged());// 删除成功输出true,否则为false } /** * 添加文档 * * @throws IOException */ @Test void testAddDocument() throws IOException { // 1.创建对象 User user = new User("兴趣使然的草帽路飞", 22); // 2.创建请求 IndexRequest request = new IndexRequest("csp_index"); // 3.构建请求规则:PUT /csp_index/_doc/1 request.id("1"); request.timeout(TimeValue.timeValueSeconds(1)); //request.timeout("1s"); // 4.将user对象数据放入请求,json 数据: 需要用到fastjson request.source(JSON.toJSONString(user), XContentType.JSON); // 5.客户端发送请求,获取响应的结果 IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT); // 输出结果 // IndexResponse[index=csp_index,type=_doc,id=1,version=1,result=created,seqNo=0,primaryTerm=1,shards={"total":2,"successful":1,"failed":0}] System.out.println(indexResponse.toString()); System.out.println(indexResponse.status());// CREATED:表示创建成功 } /** * 获取文档,判断是否存在 * * @throws IOException */ @Test void testIsExists() throws IOException { // 1.判断文档是否存在的请求 GetRequest request = new GetRequest("csp_index", "1"); // 2.执行请求:判断文档是否存在 boolean exists = client.exists(request, RequestOptions.DEFAULT); // 输出结果 System.out.println(exists);// 存在返回true,否则返回false } /** * 获取文档信息 * * @throws IOException */ @Test void testGetDocument() throws IOException { // 1.获取文档信息的请求 GetRequest getRequest = new GetRequest("csp_index", "1"); // 2.执行获取文档信息的请求 GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT); // 输出结果 System.out.println(getResponse.getSourceAsString()); //{"age":22,"name":"兴趣使然的草帽路飞"} System.out.println(getResponse);// 返回的全部内容和命令 是一样的: // {"_index":"csp_index","_type":"_doc","_id":"1","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"age":22,"name":"兴趣使然的草帽路飞"}} } /** * 更新文档信息 * * @throws IOException */ @Test void testUpdateDocument() throws IOException { // 1.更新文档请求 UpdateRequest updateRequest = new UpdateRequest("csp_index", "1"); // 设置请求超时时间 updateRequest.timeout("1s"); // user数据对象封装到json中 User user = new User("兴趣使然的诺诺亚索隆", 23); updateRequest.doc(JSON.toJSONString(user), XContentType.JSON); // 2.执行更新文档请求 UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT); // 输出结果 System.out.println(updateResponse.status());// OK:表示更新成功 } /** * 删除文档记录 * * @throws IOException */ @Test void testDeleteDocument() throws IOException { // 1.删除文档请求 DeleteRequest deleteRequest = new DeleteRequest("csp_index", "1"); deleteRequest.timeout("1s"); // 2.执行删除文档请求 DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT); // 输出结果 System.out.println(deleteResponse.status());// OK:表示删除成功 } /** * 批量插入数据 * * @throws IOException */ @Test void testBulkRequest() throws IOException { // 1.批处理请求 BulkRequest bulkRequest = new BulkRequest(); bulkRequest.timeout("10s"); // user数据集合 ArrayList<User> list = new ArrayList<>(); list.add(new User("路飞", 1)); list.add(new User("索隆", 2)); list.add(new User("山治", 3)); list.add(new User("娜美", 4)); list.add(new User("罗宾", 5)); list.add(new User("乔巴", 6)); list.add(new User("乌索普", 7)); list.add(new User("弗兰奇", 8)); list.add(new User("布鲁克", 9)); list.add(new User("甚平", 10)); for (int i = 0; i < list.size(); i++) { // 批量更新,修改,删除 都是在此进行操作 bulkRequest.add( new IndexRequest("csp_index") // 批量赋值文档id: 如果不在自己赋值文档id,会默认生成随机的文档id .id("" + (i + 1)) // ArrayList转换成json .source(JSON.toJSONString(list.get(i)), XContentType.JSON) ); } // 2.执行批量插入请求 BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT); // 输出结果 System.out.println(bulkResponse.status());// OK: 表示批量插入成功! } /** * ES中数据搜索: * SearchRequest 搜索请求 * SearchRequest 搜索请求 * SearchSourceBuilder 条件构造 * HighlightBuilder 构建高亮 * TermQueryBuilder 精确查询 * XXXQueryBuilder 构建我们需要用到的命令 * * @throws IOException */ @Test void testSearch() throws IOException { // 1.创建搜索请求 SearchRequest searchRequest = new SearchRequest("csp_index"); // 2.构建搜索条件:条件构造器SearchSourceBuilder SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 高亮结果的条件构造器 HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field("name");// 要高亮的字段 highlightBuilder.requireFieldMatch(false);// 不需要多个字段高亮,如果需要设置为true highlightBuilder.preTags("<span style='color:red'>"); highlightBuilder.postTags("</span>"); // 条件构造器,开启搜索结果高亮,并加入高亮结果的条件构造器 sourceBuilder.highlighter(highlightBuilder); /** * 查询条件,使用QueryBuilders工具类来实现: * QueryBuilders.termQuery() 精确查询 * QueryBuilders.matchAllQuery() 匹配所有 */ //TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "csp");// 精确查询 //MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();// 搜索所有数据 MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "路飞");// 搜索字段name为路飞的数据 // 查询条件(matchQueryBuilder)放入条件构造器 sourceBuilder.query(matchQueryBuilder); // 条件构造器,开启分页条件: 从第1个数据开始,每页展示5条结果数据 sourceBuilder.from(0); sourceBuilder.size(5); // 条件构造器,搜索请求超时时间60s sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); // 将条件构造器放入搜索请求 searchRequest.source(sourceBuilder); // 执行搜索请求,并获得searchResponse响应 SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 搜索得到的所有结果都封装在hits里面,拿数据从hits里面获取 SearchHits hits = searchResponse.getHits(); //System.out.println(JSON.toJSONString(hits)); // 遍历hits:解析结果,并将结果放入resultList集合 ArrayList<Map<String, Object>> resultList = new ArrayList<>(); for (SearchHit documentFields : searchResponse.getHits().getHits()) { // 获取高亮的字段 Map<String, HighlightField> highlightFields = documentFields.getHighlightFields(); HighlightField name = highlightFields.get("name");// 获取高亮的字段 Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();// 先获取原来未高亮的结果 // 解析高亮的字段, 将原来未高亮的title字段换成高亮的字段 if (name != null) { Text[] fragments = name.fragments(); String newName = ""; for (Text text : fragments) { newName += text; } // 高亮字段替换原来内容 sourceAsMap.put("name", newName); } resultList.add(documentFields.getSourceAsMap()); } // 遍历resultList resultList.forEach(item -> { System.out.println(item);// {name=<span style='color:red'>路</span><span style='color:red'>飞</span>, age=1} }); } }