ElasticSearch 的基本搭建
初步基本安装
下载Es 下载地址: https://www.elastic.co/cn/downloads/elasticsearch
选择需要的版本,以及操作系统
根据版本下载完成后,直接解压即可
直接在bin目录中点击elasticSearch即可启动,访问 http://localhost:9200
安装可视化界面 head插件
访问https://github.com/mobz/elasticsearch-head 下载包
完成后解压,确保环境正常 node.js ,python
#安装组件
npm install
#启动项目
npm run start
#启动成功后访问 http://localhost:9100即可成功访问
但是访问页面之后连接不上9200 es服务,因为es默认没有配置跨域访问
cd es服务目录/config
vim elasticsearch.yml
在最后添加,2句即可开启跨域访问,重启之后到9100重新连接即可连接成功
http.cors.enabled: true
http.cors.allow-origin: "*"
安装Kibana
到官网下载https://www.elastic.co/cn/downloads/kibana 要与es的版本保持一致
将包进行解压,直接到bin目录中kibana双击直接启动即可
启动完成后访问 http://localhost:5601
汉化
vim kibana目录/config/kibana.yml
#在最后一行添加
i18n.locale: "zh-CN"
#重启kibana
IK分词器插件的安装与使用
下载地址 : https://github.com/medcl/elasticsearch-analysis-ik 注意版本对应问题
下载完成后放到es的插件目录下
cd es安装目录/plugins
#解压下载的文件即可,解压完成之后重启es
进入kibana的测试工具,进行一下测试
两种分词模式ik_max_word 为最细粒度切分
GET _analyze
{
"analyzer": "ik_max_word",
"text": ["泪流满面"]
}
ik_smart为最少切分
GET _analyze
{
"analyzer": "ik_smart",
"text": ["泪流满面"]
}
自定义词典
换了一个词,发现这个词被拆分了,我们不想让其拆分,需要把该词添加到自定义词典中。
向ik分词器中添加自己的配置
cd es安装目录/plugins/ik/conf/
#找到IKAnalyzer.cfg.xml 进行编辑
在ik目录下新建my.dic在文件内添加想要不被切分的词组,保存
cd es安装目录/plugins/ik/conf/
#找到IKAnalyzer.cfg.xml 进行编辑
在此处添加自己的dic文件,重启es
重启之后再次执行请求,就办成一个词组了,es不会将其拆分
关于索引的基本数据操作
ES所有操作都是基于RESTFUL风格的API接口
索引---其实就是数据库
文档---每一条的数据
类型---更像是一种文档的分类方式
数据类型
PUT 初步测试
1.创建一个索引
PUT /索引名/类型名/文档id # 类型名不写默认为_doc 在8.0版本之后会弃用类型这个概念
{
请求体
}
添加完成之后到head中即可查看到数据
2.创建一条索引,并且制定字段类型(如果不设置的话在新增文档数据的时候,将会自动根据值生成对应类型)
PUT /索引名
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"length": {
"type": "integer"
}
}
}
}
GET 初步测试
1.获取索引的信息
GET /索引名
2.获取系统所有索引的信息数据
GET /_cat/indices?v
3.获取系统健康状态
GET /_cat/
POST 修改初步测试 (可以通过PUT命令直接覆盖掉原数据也可以达到更新的目的,老版本使用该方法)
1.修改文档
POST /索引名/类型名/文档id/_update
{
doc : {
要修改的字段
}
}
删除
#写到哪一步就会删到哪一步
DELETE /索引名
DELETE /索引名/类型名/文档id
关于文档的基本操作
1.简单的查询
#根据文档id查询
GET /索引名/类型名/文档id
#根据类型查询类型的所有数据
GET /索引名/类型名/_search
2.复杂查询
根据值匹配查询
#匹配拥有内容的数据,并将输出数据没用的字段去掉
GET /索引名/类型名/_search
{
"query" : {
"match": {
"name": "张" # 需要匹配的字段与值 多个条件用空格隔开
}
},
"_source" : ["name","length"] # 需要保留的字段
}
查询结果排序
#匹配拥有内容的数据,并将输出数据没用的字段去掉,并根据某个字段排序
GET /索引名/类型名/_search
{
"query" : {
"match": {
"name": "张"
}
},
"_source" : ["name","length"],
"sort": [
{
"length" : { #要排序的字段
"order" : "desc" #升序or降序
}
}
]
}
分页
#匹配拥有内容的数据,并将输出数据没用的字段去掉,并根据某个字段排序 , 并对结果进行分页
GET /索引名/类型名/_search
{
"query" : {
"match": {
"name": "张"
}
},
"_source" : ["name","length"],
"sort": [
{
"length" : {
"order" : "desc"
}
}
],
"from" : 0, #要查询第几页
"size" : 1 #每一页有几条数据
}
多条件匹配查询
# must 对应的与逻辑and 所有条件都要满足
# should 对应的或逻辑or 满足其中之一
# must_not 对应的与逻辑and 所有条件都要不满足 (长度不是18的并且姓名没有张的)
# should_not 对应的或逻辑or 不满足其中之一
GET /索引名/类型名/_search
{
"query": {
"bool": {
"must": [ #should 对应的或逻辑or 满足其中之一
{
"match": {
"name": "张"
}
},{
"match": {
"length": 18
}
}
]
}
}
}
添加过滤条件后查询
#查询长度length 大于等于3的并且小于等于19的数据
GET /索引名/类型名/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "张"
}
}
],
"filter": [
{
"range": {
"length": {
"gte": 3, #大于等于
"lte": 19 #小于等于
}
}
}
]
}
}
}
高亮查询
#选定某一或几个字段进行高亮显示
GET /索引名/_search
{
"query": {
"match": {
"name": "张"
}
}
, "highlight": {
"fields": {
"name": {} #要高亮的字段
}
}
}
#自定义高亮的标签样式
GET /索引名/_search
{
"query": {
"match": {
"name": "张"
}
}
, "highlight": {
"pre_tags": "<p class='high'>", #前标签
"post_tags": "</p>", #后标签
"fields": {
"name": {}
}
}
}
Spring Boot集成使用
引入maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
spring 默认导入的依赖包版本大可能与我们本地的es版本不一致
自动导入包的版本为6.8.6而本地的包版本为7.8.0,需要修改一下包的版本
<elasticsearch.version>7.8.0</elasticsearch.version>
在yml中添加配置
server:
port: 8080
spring:
application:
name: es-client-study
es:
host: "127.0.0.1"
port: 9200
scheme: "http"
新建RestEsClientConfig.java 用来向springboot注入es的相关bean
@Configuration
public class RestEsClientConfig {
@Value("${es.host}")
private String host;
@Value("${es.port}")
private Integer port;
@Value("${es.scheme}")
private String scheme;
@Bean
public RestHighLevelClient restHighLevelClient(){
return new RestHighLevelClient(RestClient.builder(
new HttpHost(host,port,scheme)
));
}
}
到测试类中进行测试
开始API操作测试
索引系列操作
1.新建一个索引
@SpringBootTest
@RunWith(SpringRunner.class)
public class EsStudyApplicationTests {
@Autowired
@Qualifier("restHighLevelClient")
private RestHighLevelClient client;
//新建索引
@Test
public void createIndex() throws IOException {
//1.创建索引请求
CreateIndexRequest test_index = new CreateIndexRequest("test_index");
//2.执行创建索引请求获得相应
CreateIndexResponse createIndexResponse = client.indices().create(test_index, RequestOptions.DEFAULT);
System.out.println(createIndexResponse.toString());
}
}
2,如果索引存在获取索引信息
//如果索引存在获取索引信息
@Test
public void getIndex() throws IOException {
//1.创建 获取索引请求
GetIndexRequest getIndexRequest = new GetIndexRequest("test_index2");
//2.判断是否存在
boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
if (exists) {
//3.执行获取请求
GetIndexResponse getIndexResponse = client.indices().get(getIndexRequest, RequestOptions.DEFAULT);
System.out.println(getIndexResponse.getIndices());
} else {
System.out.println("-------索引不存在-------");
}
}
3.删除索引
//删除索引
@Test
public void deleteIndex() throws IOException {
//1.创建 删除索引请求
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("test_index");
//2.执行请求
AcknowledgedResponse delete = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
//输出是否删除成功
System.out.println(delete.isAcknowledged());
}
文档系列操作
1.通过实体类添加文档
//测试通过实体类添加文档
@Test
public void addWord() throws IOException {
//创建实体类对象
User user = new User(18, "张三");
//获取索引操作对象
IndexRequest indexRequest = new IndexRequest("test_indexs");
//设置文档创建的相关规则 PUT 索引名/类型名/文档id
indexRequest.id("1");
//设置请求的超时时间
indexRequest.timeout("1s");
//将数据放入请求中,将user对象转化为字符串
IndexRequest source = indexRequest.source(JSON.toJSONString(user),XContentType.JSON);
//发送请求 获取相应结果
IndexResponse index = client.index(indexRequest, RequestOptions.DEFAULT);
System.out.println("*************index : " + index.toString());
System.out.println("*************status : " + index.status());
}
2.存在获取文档信息
//存在获取文档信息
@Test
public void testGetWord() throws IOException {
GetRequest getRequest = new GetRequest("test_indexs", "1");
//设置不返回_source的上下文信息,提高查询是否存在的效率
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
if (exists) {
//如果存在在构建新的getRequest查询
GetRequest request = new GetRequest("test_indexs", "1");
GetResponse documentFields = client.get(request, RequestOptions.DEFAULT);
System.out.println("***********docFile:"+documentFields.getSourceAsString());
System.out.println(documentFields);
}else {
System.out.println("***********文档不存在");
}
}
3.修改文档信息
//更新文档信息
@Test
public void updateWord() throws IOException {
//创建更新请求
UpdateRequest updateRequest = new UpdateRequest("test_indexs", "1");
updateRequest.timeout("1s");
//创建更新信息
User user = new User(10, "李四");
//设置请求参数
updateRequest.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);
System.out.println(response.status());
}
4,删除文档信息
//删除文档信息
@Test
public void deleteWord() throws IOException {
//创建删除请求
DeleteRequest deleteRequest = new DeleteRequest("test_indexs", "1");
deleteRequest.timeout("1s");
//发送请求
DeleteResponse delete = client.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(delete.status());
}
5.批量添加文档数据
//批量添加文档数据
@Test
public void addBulkWord() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
ArrayList<User> users = new ArrayList<>();
users.add(new User(12,"张3"));
users.add(new User(13,"张4"));
users.add(new User(14,"张5"));
users.add(new User(15,"张6"));
users.add(new User(16,"张7"));
users.add(new User(17,"张8"));
users.add(new User(18,"张9"));
users.add(new User(19,"张10"));
users.add(new User(20,"张11"));
//批处理请求
for (int i = 0; i < users.size(); i++) {
bulkRequest.add(
new IndexRequest("test_index")
.id(""+(i+1))
.source(JSON.toJSONString(users.get(i)),XContentType.JSON)
);
}
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.status());
System.out.println(bulk.hasFailures());
}
文档系列查询操作
//查询操作
@Test
public void testSearch() throws IOException {
//创建搜索请求
SearchRequest searchRequest = new SearchRequest("test_index");
//构建搜索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//高亮显示
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("name");
highlightBuilder.preTags("<p class='highlight'>");
highlightBuilder.postTags("</p>");
sourceBuilder.highlighter(highlightBuilder);
//构建查询条件对象
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("name", "张");
sourceBuilder.query(queryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//将查询条件放入查询请求中
searchRequest.source(sourceBuilder);
//发送查询条件
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(search.getHits().getHits()));
}