ElasticSearch
TODO
版本选择官网
ES:6.8.6
Docker 安装
docker run -d --name es6.8.6 -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" -e "discovery.type=single-node" -p 9200:9200 -p 9300:9300 elasticsearch:6.8.6
elasticsearch:6.8.6 可以
docker pull
拉取
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m"
:内存大小
-e "discovery.type=single-node"
:非集群模式
可视化工具 使用 ElisticHD
项目快速搭建
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath />
</parent>
<!-- 引入 elasticsearch 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
server:
port: 8080
tomcat:
uri-encoding: UTF-8
spring:
application:
name: service-search
data:
elasticsearch:
#7.0 版本换了一种配置方式,这里会有过时线,不用理会
cluster-name: docker-cluster # 访问 9200 查看
实体类
@Document(indexName = "test" , type = "_doc") //type 在7.0 被弃用
public class User implements Serializable {
@Id
private Long id;
//@Field(type = FieldType.Text) //field es的映射 注意:映射不一定要写在代码中,可能需要在 es中写
@Field
private String city;
//@Field(type = FieldType.Keyword)
@Field
private String username;
//@Field(type = FieldType.Double)
@Field
private Double salary;
}
package com.example.elasticsearch.controller;
import com.example.elasticsearch.pojo.User;
import org.elasticsearch.action.index.IndexRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.GetQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
/**
* @author LFweixiao
* @create 2022-05-14 9:26 上午
*/
@RestController
public class TemplateController {
public static User user=new User(1L,"武汉","lf",2000.0);
//data 提供的模版
@Autowired
public ElasticsearchTemplate esTemplate;
/*
创建index
*/
@GetMapping("index")
public String createIndex() {
esTemplate.createIndex(User.class);
return "添加index 表";
}
/*
删除
*/
@GetMapping("deleteIndex")
public String deleteIndex() {
esTemplate.deleteIndex(User.class);
return "删除index";
}
/*
添加 行数据
*/
@GetMapping("addDoc")
public String addDocument() {
IndexQuery query = new IndexQueryBuilder()
.withObject(user)
.build();
esTemplate.index(query);
return "添加Doc";
}
/*
修改
*/
@GetMapping("update/{message}")
public String updateDocument(@PathVariable String message) {
//需要修改的内容 字段
HashMap<String, Object> map = new HashMap<>();
map.put("city",message);
IndexRequest ir = new IndexRequest();
ir.source(map);
UpdateQuery uq = new UpdateQueryBuilder()
.withClass(User.class) //表 index
.withId("1") // 数据id
.withIndexRequest(ir)
.build();
esTemplate.update(uq);
return "传入值修改 目前id 写死";
}
/*
查询 id 写死
*/
@GetMapping("getDoc")
public String getDoc() {
GetQuery getQuery = new GetQuery();
getQuery.setId("1");
User user = esTemplate.queryForObject(getQuery, User.class);
System.out.println( user.toString() );
return user.toString() + " id 写死";
}
/*
删除 行
*/
@GetMapping("deleteDoc")
public String deleteDocument() {
esTemplate.delete(User.class,"1");
return "删除Dod测试";
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zGCwMZ3O-1652782958621)(ElasticSearch.assets/image-20220516132420547.png)]
/*
查询所有
*/
@GetMapping("list")
public String listAll() {
//es 的也没是从0开始计算的 分页
PageRequest page = PageRequest.of(0, 10);
SearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchAllQuery())
.withPageable(page)
.build();
AggregatedPage<User> users = esTemplate.queryForPage(query, User.class);
List<User> list = users.getContent();
return list.stream().map(User::toString).collect(Collectors.joining(",","{","}"));
}
/*
完全匹配查询
QueryBuilders.termQuery("字段名",匹配值)
*/
@GetMapping("term/{field}")
public String terms(@PathVariable String field) {
SearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.termQuery("city","武汉"))
.build();
List<User> list = esTemplate.queryForList(query, User.class);
return list.stream().map(User::toString).collect(Collectors.joining(",","{","}"));
}
/*
关键字匹配
将关键字 分词后,查询所有匹配的结果
*/
@GetMapping("match/{message}")
public String match(@PathVariable String message) {
SearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchQuery("city","武汉"))
.build();
List<User> list = esTemplate.queryForList(query, User.class);
return list.stream().map(User::toString).collect(Collectors.joining(",","{","}"));
}
基础部分
ES核心 | 类似mysql |
---|---|
index | 表 |
type (7.0 弃用) | 表的逻辑类型 |
document | 行 |
fields | 列 |
mapping (添加数据,会自动创建映射,建议还是编写) | 表结构,字段类型 |
NRT 近实时(Near real time 接近真实时间) | |
node | 每一个服务器 |
shard replica | 数据分片与备份 |
正排索引:
类似mysql 的按照 主键id。去寻找值
倒排索引:
会对内容切分成类似我爱我家
被按照一定方式切分ids我爱、我家、我爱我、我、爱..
用数字去记录
倒排索引:
根据属性的值 去查询数据库,根据单词(列子: 我爱 )去搜索它的文档dis ,速度会非常快。
java 例子 | es查询 | 效果 |
---|---|---|
Integer 8 | “query”:{“term”:{…}} | term 完全匹配 |
String “我的” | “query”:{“match”:{…}} | match 分词匹配 (我、的、我的) |
“query”:{“match_all”:{…}} | match_all 查询所有 |
自动方法规则
关键字 | 命名规则 | 解释 | 例子 |
---|---|---|---|
and | findByField1AndField2 | 根据Field1和Field2 | findByTitleAndPrice |
or | findByField1OrField2 | 根据Field1或Field2 | findByTileOrPrice |
is | findByField | 根据Field获取数据 | findByTitle |
not | finfByFieldNot | 根据Field获得部集数据 | findByTitleNot |
between | findByFieldBetween | 获得指定范围数据 | findByPriceBetween |
lessThanEqueal | findByFieldLessThan | 获得小于指定值的数据 | findByPriceLessThan |