ElasticSearch入门篇

控制台RESTFULL操作

使用工具Cerebro v0.8.3

REST风格说明

一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简介,更有层次,更易于实现缓存等机制

基于REST命令说明:

methodurl地址描述
PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)
POSTlocalhost:9200/索引名称/类型名称创建文档(随机文档id)
POSTlocalhost:9200/索引名称/类型名称/文档id/_update更新文档
DELETElocalhost:9200/索引名称/类型名称/文档id删除文档
GETlocalhost:9200/索引名称/类型名称/文档id通过docId查询文档
POSTlocalhost:9200/索引名称/类型名称/_search查询所有数据

es支持的数据类型

核心数据类型

(1)字符串类型: text, keyword

(2)数字类型:long, integer, short, byte, double, float, half_float, scaled_float

(3)日期:date

(4)日期 纳秒:date_nanos

(5)布尔型:boolean

(6)Binary:binary

(7)Range: integer_range, float_range, long_range, double_range, date_range

其他类型

ik分词器使用

ik_smart最少切分

请求服务名:_analyze
请求方式:GET
请求体:

{
    "analyzer":"ik_smart",
    "text":" 和尚和未结婚的和尚结婚了"
}

返回:

{
  "tokens": [
    {
      "token": "和尚",
      "start_offset": 1,
      "end_offset": 3,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "和",
      "start_offset": 3,
      "end_offset": 4,
      "type": "CN_CHAR",
      "position": 1
    },
    {
      "token": "未",
      "start_offset": 4,
      "end_offset": 5,
      "type": "CN_CHAR",
      "position": 2
    },
    {
      "token": "结婚",
      "start_offset": 5,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 3
    },
    {
      "token": "的",
      "start_offset": 7,
      "end_offset": 8,
      "type": "CN_CHAR",
      "position": 4
    },
    {
      "token": "和尚",
      "start_offset": 8,
      "end_offset": 10,
      "type": "CN_WORD",
      "position": 5
    },
    {
      "token": "结婚",
      "start_offset": 10,
      "end_offset": 12,
      "type": "CN_WORD",
      "position": 6
    },
    {
      "token": "了",
      "start_offset": 12,
      "end_offset": 13,
      "type": "CN_CHAR",
      "position": 7
    }
  ]
}

操作截图
在这里插入图片描述

ik_max_word最细粒度

请求服务名:_analyze
请求方式:GET
请求体:

{
    "analyzer":"ik_max_word",
    "text":" 和尚和未结婚的和尚结婚了"
}

返回:

{
  "tokens": [
    {
      "token": "和尚",
      "start_offset": 1,
      "end_offset": 3,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "和",
      "start_offset": 3,
      "end_offset": 4,
      "type": "CN_CHAR",
      "position": 1
    },
    {
      "token": "未结",
      "start_offset": 4,
      "end_offset": 6,
      "type": "CN_WORD",
      "position": 2
    },
    {
      "token": "结婚",
      "start_offset": 5,
      "end_offset": 7,
      "type": "CN_WORD",
      "position": 3
    },
    {
      "token": "的",
      "start_offset": 7,
      "end_offset": 8,
      "type": "CN_CHAR",
      "position": 4
    },
    {
      "token": "和尚",
      "start_offset": 8,
      "end_offset": 10,
      "type": "CN_WORD",
      "position": 5
    },
    {
      "token": "结婚",
      "start_offset": 10,
      "end_offset": 12,
      "type": "CN_WORD",
      "position": 6
    },
    {
      "token": "了",
      "start_offset": 12,
      "end_offset": 13,
      "type": "CN_CHAR",
      "position": 7
    }
  ]
}

操作截图:

在这里插入图片描述

索引操作

索引库创建

mappings好比mysql数据库中创建表结构,es通过mappings来创建索引规则

PUT 索引库名称

例如:PUT test2

{
    "mappings":{
        "properties":{
            "name":{
                "type":"text"
            },
            "age":{
                "type":"long"
            },
            "birthday":{
                "type":"date"
            }
        }
    }

}

返回:

{
  "acknowledged": true,
  "shards_acknowledged": true,
  "index": "test2"
}

在这里插入图片描述

查看索引库是否创建成功:GET test2

{
  "test2": {
    "aliases": {

    },
    "mappings": {
      "properties": {
        "age": {
          "type": "long"
        },
        "birthday": {
          "type": "date"
        },
        "name": {
          "type": "text"
        }
      }
    },
    "settings": {
      "index": {
        "creation_date": "1605249683965",
        "number_of_shards": "1",
        "number_of_replicas": "1",
        "uuid": "TuEFwhYdRHC01ZRvkcZiGQ",
        "version": {
          "created": "7070099"
        },
        "provided_name": "test2"
      }
    }
  }
}

创建文档方式

如果索引库没有配置mapping,es会给我们默认配置字段类型

methodurl地址描述
PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)
指定索引类型(以后这种方式会被弃用)

在这里插入图片描述

不指定索引类型利用默认的_doc类型

PUT test3/_doc/1

{
    "name":"魏杰",
    "age":25,
    "birth":"1995-10-01"
}  

返回:

{
  "_index": "test3",
  "_type": "_doc",
  "_id": "1",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 0,
  "_primary_term": 1
}

在这里插入图片描述
查看索引库会自动配置默认字段类型
请求:GET test2
返回:

{
  "test2": {
    "aliases": {

    },
    "mappings": {
      "properties": {
        "age": {
          "type": "long"
        },
        "birth": {
          "type": "date"
        },
        "birthday": {
          "type": "date"
        },
        "name": {
          "type": "text"
        }
      }
    },
    "settings": {
      "index": {
        "creation_date": "1605249683965",
        "number_of_shards": "1",
        "number_of_replicas": "1",
        "uuid": "TuEFwhYdRHC01ZRvkcZiGQ",
        "version": {
          "created": "7070099"
        },
        "provided_name": "test2"
      }
    }
  }
}

在这里插入图片描述

更新文档

修改 提交还是使用PUT即可!然后覆盖!最新办法使用update!

方式一:
PUT test3/_doc/1
{
    "name":"魏杰2",
    "age":21,
    "birth":"1995-11-01"
    
}

返回:

{
  "_index": "test3",
  "_type": "_doc",
  "_id": "1",
  "_version": 2,
  "result": "updated",
  "_shards": {
    "total": 2,
    "successful": 1,
    "failed": 0
  },
  "_seq_no": 1,
  "_primary_term": 1
}

_version可以看出版本号发生了更新,result是updated表示发生了更新
这种更新方式的缺点是每次都需要传所有数据,而不能指定某个域去更新数据

方式二:推荐使用这种方式修改更加高效
POST test3/_doc/1/_update
{
    "doc":{
        "name":"盲僧"
    }
}

删除操作

通过DELETE命令实现删除,根据你的请求来判断是删除索引还是删除文档记录!
使用RESTFUL风格是es推荐大家使用的

查询操作

按照id查询

GET user/_doc/1

搜索

简单查询
GET user/_doc/_search?q=name:c
匹配
GET user/_doc/_search
{
    "query":{
        "match":{
            "name":"c"
        }
    }
}

在这里插入图片描述

结果过滤:

_source:字段用来过滤搜索出的结果

GET user/_doc/_search
{
    "query":{
        "match":{
            "name":"c"
        }
    },
    "_source":["name","age"]
}
排序

利用sort构建排序,asc:升序、desc:降序 可以结合mysql来记忆

GET user/_doc/_search
{
    "query":{
        "match":{
            "name":"c"
        }
    },
    "sort":[
        {
            "age":{
                "order":"desc"
            }
        }]
}
分页查询

添加from、size参数即可

GET user/_doc/_search
{
    "query":{
        "match":{
            "name":"c"
        }
    },
    "sort":[
        {
            "age":{
                "order":"desc"
            }
        }],
    "from":0,
    "size":1
}
匹配多个条件

利用空格隔开

user/_doc/_search
{
    "query":{
        "match":{
            "name":"c java"
        }
    }
}

在这里插入图片描述

精确查询

term查询是直接通过倒排索引指定的词条进行精确查找的
关于分词:

  • term:直接从倒排中精准查询
  • match:会使用分词器解析,先分析文档,然后再查询

两个类型 text 和 keyword

  • keyword类型不会被分词器分词,keyword类型只能被精准查询
  • text类型会被分词器分词
    在这里插入图片描述

利用term + bool可以精确查询多个值

高亮查询

默认高亮标签

highlight->fields->name:表示对name字段值输出高亮显示

{
    "query":{
        "bool":{
            "should":[
                {
                    "match":{
                    "name":"杰"
                    }
                }
            ]
        }
    },
    "highlight":{
        "fields":{
            "name":{}
        }
    }
}

在这里插入图片描述

自定义高亮标签
{
    "query":{
        "bool":{
            "should":[
                {
                    "match":{
                    "name":"杰"
                    }
                }
            ]
        }
    },
    "highlight":{
        "pre_tags":"<p class='key' style='color:red'>",
        "post_tags":"</p>",
        "fields":{
            "name":{}
        }
    }
}

在这里插入图片描述

布尔查询

加上bool参数

match

对应mysql中的and,两个条件必须都满足

GET user/_doc/_search
{
    "query":{
        "bool":{
            "must":[
                {
                    "match":{
                    "name":"c"
                    }
                },
                {
                    "match":{
                        "age":25
                    }
                }
            ]
        }
    }
}
should

对应mysql中的or,两个满足一个即可

GET user/_doc/_search
{
    "query":{
        "bool":{
            "should":[
                {
                    "match":{
                    "name":"c"
                    }
                },
                {
                    "match":{
                        "age":28
                    }
                }
            ]
        }
    }
}
must_not

对应mysql中的not

GET user/_doc/_search
{
    "query":{
        "bool":{
            "must_not":[
                {
                    "match":{
                    "name":"c"
                    }
                }
            ]
        }
    }
}
filter

利用filter对数据过滤,区间查询

GET user/_doc/_search
{
    "query":{
        "bool":{
            "must":[
                {
                    "match":{
                    "name":"c"
                    }
                }
            ],
            "filter":{
                "range":{
                    "age":{
                        "lt":25
                    }
                }
            }
        }
    }
}
  • gt:大于
  • gte:大于等于
  • lt:小于
  • lte:小于等于!

java API使用

官方文档

RestClient和TransportClient区别?

TransportClient基于TCP协议、Rest Client 基于Http协议;
详细说明:https://blog.csdn.net/huoqilinheiqiji/article/details/89713412

Java Low Level REST Client 和 Java High Level REST Client区别?

低级别客户端:允许通过http请求与es集群进行通信,API本身不负责数据的编码解码,由用于去编码解码,它与所有的es版本兼容。

高级别客户端:es官方高级客户端,基于低级客户端,它定义的API,已经对请求与响应数据包进行编解码

API使用

获取连接

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));
        return client;
    }

创建索引库

	/**
	 * 创建索引库 PUT test_index
	 */
	@Test
	void createIndex() throws IOException {
		//1.创建索引请求
		CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);
		//2.执行创建请求,获取响应 indices:index复数
		CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
		System.out.println(createIndexResponse);
	}

删除索引库/判断索引库是否存在

	/**
	 * 获取索引库 GET test_index
	 */
	@Test
	void testExistIndex() throws IOException {
		GetIndexRequest request = new GetIndexRequest(INDEX_NAME);
//		new DeleteIndexRequest() 删除索引库
		boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
		Assertions.assertEquals(true, exists);
	}

添加文档

	/**
	 * 添加文档
	 * PUT test_index/_doc/1
	 * {
	 *     "name":"小明",
	 *     "age":"25";
	 * }
	 */
	@Test
	void createDocument() throws IOException {
		//创建对象
		User user = new User("小明", 25);
		//创建请求
		IndexRequest indexRequest = new IndexRequest(INDEX_NAME);
		// PUT indexName/_doc/1
		indexRequest.id("1").timeout(TimeValue.timeValueSeconds(1));
		//将我们的数据放入请求 json
		indexRequest.source(JSON.toJSONString(user), XContentType.JSON);

		//客户端发送请求
		IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
		//对应我们命令返回的状态:created/updated
		System.out.println(indexResponse.status());
		System.out.println(indexRequest.toString());
	}

更新文档

	/**
	 * 更新文档方式一:
	 * PUT test_index/_doc/1
	 * {
	 *     "name":"小红",
	 *     "age":"25"
	 * }
	 * 更新文档方式二:
	 * PUT test_index/_doc/1/_update
	 * {
	 *     "doc"{
	 *         "name":"小红"
	 *     }
	 * }
	 */
	@Test
	void updateDocument() throws IOException {
		UpdateRequest updateRequest = new UpdateRequest(INDEX_NAME, "1");
		//方式一
//		HashMap<String, Object> updateFieldsMap = new HashMap<>();
//		updateFieldsMap.put("name", "小红");
//		updateRequest.doc(updateFieldsMap);
		//方式二
		User user = new User("疾风剑豪",25);
		updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);

		client.update(updateRequest, RequestOptions.DEFAULT);
		queryDocument();
	}

获取新闻文档

	/**
	 * 获取文档
	 * GET test_index/_doc/1
	 */
	@Test
	void queryDocument() throws IOException{
		GetRequest request = new GetRequest(INDEX_NAME);
		request.id("1");
		//不返回 _source结果,效率更高
//		request.fetchSourceContext(new FetchSourceContext(false));
		//设置某个字段单独放在GetResponse对象中
//		request.storedFields("_none_");
		//判断文档是否存在
//		boolean exists = client.exists(request, RequestOptions.DEFAULT);
		GetResponse response = client.get(request, RequestOptions.DEFAULT);
		String cnt = response.getSourceAsString();
		System.out.println(cnt);
		//返回全部内容和命令一样
		/**
		 * {
		 *   "_index": "test_index",
		 *   "_type": "_doc",
		 *   "_id": "1",
		 *   "_version": 1,
		 *   "_seq_no": 0,
		 *   "_primary_term": 1,
		 *   "found": true,
		 *   "_source": {
		 *     "age": 25,
		 *     "name": "小明"
		 *   }
		 * }
		 */
		System.out.println(response);
	}

批量插入文档

	/**
	 * 批量插入数据
	 */
	@Test
	void bulkRequest() throws IOException {
		BulkRequest bulkRequest = new BulkRequest();
		bulkRequest.timeout("10s");
		for (int i = 2; i < 10; i++){
			User user = new User("name-" + i, i);
			IndexRequest indexRequest = new IndexRequest(INDEX_NAME);
			//不用id会生成一个随机的id
			indexRequest.id(i + "").source(JSON.toJSONString(user), XContentType.JSON);
			bulkRequest.add(indexRequest);
		}
		client.bulk(bulkRequest, RequestOptions.DEFAULT);
	}

搜索

	/**
	 * 查询
	 * GET test_index/_doc/_search?
	 * {
	 *     "query":{
	 *         "match":"name:剑豪"
	 *     }
	 * }
	 */
	@Test
	void search() throws IOException {
		SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
		//构建搜索条件,我们可以使用QueryBuilders工具来实现
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		/**
		 "highlight":{
		 "pre_tags":"<p class='key' style='color:red'>",
		 "post_tags":"</p>",
		 "fields":{
		 "name":{}
		 }
		 }
		 */
		HighlightBuilder highlightBuilder = new HighlightBuilder();
		highlightBuilder.field("name");
		//关闭多个高亮显示,只高亮首次匹配即可
		highlightBuilder.requireFieldMatch(false);
		highlightBuilder.preTags("<span style='color:red'>");
		highlightBuilder.postTags("</span>");
		sourceBuilder.highlighter(highlightBuilder);
//		QueryBuilder queryBuilder = new QueryBuilder();
		MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "name");
		sourceBuilder.query(queryBuilder);
		//设置查询超时时间
		sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//		sourceBuilder.from(0);
//		sourceBuilder.size(20);
		searchRequest.source(sourceBuilder);

		SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
		SearchHit[] hits = searchResponse.getHits().getHits();
		for (SearchHit hit : hits){
			//解析高亮的字段
			Map<String, HighlightField> highlightFields = hit.getHighlightFields();
			HighlightField name = highlightFields.get("name");
			Map<String, Object> sourceAsMap = hit.getSourceAsMap();
			//如果当前高亮字段不为null,将原来的字段换成我们高亮的字段即可
			if (name != null){
				//获取高亮的片段
				Text[] fragments = name.fragments();
				//替换
				StringBuilder stringBuilder = new StringBuilder();
				for (Text text : fragments){
					stringBuilder.append(text);
				}
				sourceAsMap.put("name", stringBuilder.toString());
			}
			System.out.println(sourceAsMap.toString());
		}
	}

springBoot整合elasticSearch 7

新建项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>csdn.dreamzuora</groupId>
	<artifactId>es-api</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>es-api</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
		<!--自定义es版本依赖,保证和自己版本一致-->
		<elasticsearch.version>7.6.1</elasticsearch.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.75</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

注意:如果当前springBoot版本默认导入的spring-boot-starter-data-elasticsearch使用的是老版本需要<elasticsearch.version>7.6.1</elasticsearch.version>中去指定版本

创建类

配置类
package csdn.dreamzuora.config;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Title: es客户端配置信息
 * Description:
 *
 * @version 1.0
 * @author: weijie
 * @date: 2020/11/19 18:15
 */
@Configuration
public class EsConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));
        return client;
    }


}

实体类
package csdn.dreamzuora.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Title:
 * Description:
 *
 * @version 1.0
 * @author: weijie
 * @date: 2020/11/19 18:40
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private int age;
}

测试类
package csdn.dreamzuora;

import com.alibaba.fastjson.JSON;
import csdn.dreamzuora.pojo.User;
import org.apache.lucene.util.QueryBuilder;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@SpringBootTest
class EsApiApplicationTests {

	@Autowired
	@Qualifier("restHighLevelClient")
	private RestHighLevelClient client;

	private String INDEX_NAME = "test_index";

	/**
	 * 创建索引库 PUT test_index
	 */
	@Test
	void createIndex() throws IOException {
		//1.创建索引请求
		CreateIndexRequest request = new CreateIndexRequest(INDEX_NAME);
		//2.执行创建请求,获取响应 indices:index复数
		CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
		System.out.println(createIndexResponse);
	}

	/**
	 * 获取索引库 GET test_index
	 */
	@Test
	void testExistIndex() throws IOException {
		GetIndexRequest request = new GetIndexRequest(INDEX_NAME);
//		new DeleteIndexRequest() 删除索引库
		boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
		Assertions.assertEquals(true, exists);
	}

	/**
	 * 添加文档
	 * PUT test_index/_doc/1
	 * {
	 *     "name":"小明",
	 *     "age":"25";
	 * }
	 */
	@Test
	void createDocument() throws IOException {
		//创建对象
		User user = new User("小明", 25);
		//创建请求
		IndexRequest indexRequest = new IndexRequest(INDEX_NAME);
		// PUT indexName/_doc/1
		indexRequest.id("1").timeout(TimeValue.timeValueSeconds(1));
		//将我们的数据放入请求 json
		indexRequest.source(JSON.toJSONString(user), XContentType.JSON);

		//客户端发送请求
		IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
		//对应我们命令返回的状态:created/updated
		System.out.println(indexResponse.status());
		System.out.println(indexRequest.toString());
	}

	/**
	 * 更新文档方式一:
	 * PUT test_index/_doc/1
	 * {
	 *     "name":"小红",
	 *     "age":"25"
	 * }
	 * 更新文档方式二:
	 * PUT test_index/_doc/1/_update
	 * {
	 *     "doc"{
	 *         "name":"小红"
	 *     }
	 * }
	 */
	@Test
	void updateDocument() throws IOException {
		UpdateRequest updateRequest = new UpdateRequest(INDEX_NAME, "1");
		//方式一
//		HashMap<String, Object> updateFieldsMap = new HashMap<>();
//		updateFieldsMap.put("name", "小红");
//		updateRequest.doc(updateFieldsMap);
		//方式二
		User user = new User("疾风剑豪",25);
		updateRequest.doc(JSON.toJSONString(user), XContentType.JSON);

		client.update(updateRequest, RequestOptions.DEFAULT);
		queryDocument();
	}

	/**
	 * 获取文档
	 * GET test_index/_doc/1
	 */
	@Test
	void queryDocument() throws IOException{
		GetRequest request = new GetRequest(INDEX_NAME);
		request.id("1");
		//不返回 _source结果,效率更高
//		request.fetchSourceContext(new FetchSourceContext(false));
		//设置某个字段单独放在GetResponse对象中
//		request.storedFields("_none_");
		//判断文档是否存在
//		boolean exists = client.exists(request, RequestOptions.DEFAULT);
		GetResponse response = client.get(request, RequestOptions.DEFAULT);
		String cnt = response.getSourceAsString();
		System.out.println(cnt);
		//返回全部内容和命令一样
		/**
		 * {
		 *   "_index": "test_index",
		 *   "_type": "_doc",
		 *   "_id": "1",
		 *   "_version": 1,
		 *   "_seq_no": 0,
		 *   "_primary_term": 1,
		 *   "found": true,
		 *   "_source": {
		 *     "age": 25,
		 *     "name": "小明"
		 *   }
		 * }
		 */
		System.out.println(response);
	}

	/**
	 * 批量插入数据
	 */
	@Test
	void bulkRequest() throws IOException {
		BulkRequest bulkRequest = new BulkRequest();
		bulkRequest.timeout("10s");
		for (int i = 2; i < 10; i++){
			User user = new User("name-" + i, i);
			IndexRequest indexRequest = new IndexRequest(INDEX_NAME);
			//不用id会生成一个随机的id
			indexRequest.id(i + "").source(JSON.toJSONString(user), XContentType.JSON);
			bulkRequest.add(indexRequest);
		}
		client.bulk(bulkRequest, RequestOptions.DEFAULT);
	}

	/**
	 * 查询
	 * GET test_index/_doc/_search?
	 * {
	 *     "query":{
	 *         "match":"name:剑豪"
	 *     }
	 * }
	 */
	@Test
	void search() throws IOException {
		SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
		//构建搜索条件,我们可以使用QueryBuilders工具来实现
		SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
		/**
		 "highlight":{
		 "pre_tags":"<p class='key' style='color:red'>",
		 "post_tags":"</p>",
		 "fields":{
		 "name":{}
		 }
		 }
		 */
		HighlightBuilder highlightBuilder = new HighlightBuilder();
		highlightBuilder.field("name");
		//关闭多个高亮显示,只高亮首次匹配即可
		highlightBuilder.requireFieldMatch(false);
		highlightBuilder.preTags("<span style='color:red'>");
		highlightBuilder.postTags("</span>");
		sourceBuilder.highlighter(highlightBuilder);
//		QueryBuilder queryBuilder = new QueryBuilder();
		MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "name");
		sourceBuilder.query(queryBuilder);
		//设置查询超时时间
		sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//		sourceBuilder.from(0);
//		sourceBuilder.size(20);
		searchRequest.source(sourceBuilder);

		SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
		SearchHit[] hits = searchResponse.getHits().getHits();
		for (SearchHit hit : hits){
			//解析高亮的字段
			Map<String, HighlightField> highlightFields = hit.getHighlightFields();
			HighlightField name = highlightFields.get("name");
			Map<String, Object> sourceAsMap = hit.getSourceAsMap();
			//如果当前高亮字段不为null,将原来的字段换成我们高亮的字段即可
			if (name != null){
				//获取高亮的片段
				Text[] fragments = name.fragments();
				//替换
				StringBuilder stringBuilder = new StringBuilder();
				for (Text text : fragments){
					stringBuilder.append(text);
				}
				sourceAsMap.put("name", stringBuilder.toString());
			}
			System.out.println(sourceAsMap.toString());
		}
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值