基本概念
ES | 数据库 |
---|---|
Index: 索引 | Schema:库 |
Type: 类型 | Table:表 |
Document: 文档 | Record: 一行记录 |
Field: 属性 | Column: 列 |
Mapping: 映射 | TableStruct: 表结构; |
操作流程:
1、创建一个索引;新版不用管类型了。
2、给这个索引下crud 文档。每个文档都是一个json;json的属性必须说明mapping类型。
{id: 8,name: ‘2017-11-11’}
3、es就可以进行检索。
正排索引:MySQL那样的 select * from movie where name like %红海行动%
1 红海行动
2 红海特别行动
3 红海特工
4 特工在红海行动
5 特工行动
6 行动红海
倒排索引:
存:分词
红海 1,2,3,4,6
行动 1,2,4,5,6
特别 2
特工 3,4,5搜:“红海行动”
分词;搜索关键字进行单词拆分; 红海 行动
找倒排索引。红海 : 1,2,3,4,6 行动:1,2,4,5,6
交集x?并集v?
找到的记录会有相关性得分;
命中率: 2/2 100% 2/3=66.66% 1/2 = 50% 2/3=66.66% 1/2 = 50% 2/2=100%
顺序: 完全命中且顺序一致,分就最高
spring-boot 整合ES
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
导入依赖后,会发现有如下的自动配置类
- ElasticsearchDataAutoConfiguration
- ElasticsearchRestTemplate: 操作es的工具类; 未来用它
- ReactiveElasticsearchTemplate: 响应式方式操作es的工具类
- ElasticsearchRepositoriesAutoConfiguration
- @EnableElasticsearchRepositories: 开启es仓库
- ElasticsearchRestClientAutoConfiguration
- 所有配置: spring.elasticsearch.rest
- RestHighLevelClient: es官方提供的最底层的操作es客户端
- RestClient: es官方提供的最底层的api:
测试:
@SpringBootTest
public class EsTest {
@Autowired
ElasticsearchRestTemplate restTemplate;
@Test
void test01(){
boolean person = restTemplate.indexOps(IndexCoordinates.of("person"))
.create();
System.out.println(person);
}
}
crud
1、创建索引
PUT /person
@Test
void testCreatIndex(){
// new DefaultIndexOperations();
boolean person = restTemplate.indexOps(IndexCoordinates.of("person"))
.create();
System.out.println(person);
}
2、保存数据
POST /person/_doc/1
{
“id”: 1,
“name”: “张三”,
“age”: 25
}
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Person {
private Long id;
private String name;
private Integer age;
}
@Test
void testPost(){
IndexQuery query = new IndexQueryBuilder().withId("1")
.withObject(new Person(1L, "张三", 18))
.build();
restTemplate.index(query,IndexCoordinates.of("person"));
}
3、查询文档
GET /person/_doc/1
@Test
void testQuery(){
Person person = restTemplate.get("1", Person.class, IndexCoordinates.of("person"));
System.out.println(person);
}
4、修改文档
POST /person/_doc/1
{
“id”: 1,
“name”: “张三”,
“age”: 26
}
@Test
void testPost(){
IndexQuery query = new IndexQueryBuilder().withId("1")
.withObject(new Person(1L, "张三", 19))
.build();
restTemplate.index(query,IndexCoordinates.of("person"));
}
5、删除文档
DELETE /person/_doc/1
@Test
void testDelete(){
String person = restTemplate.delete("1", IndexCoordinates.of("person"));
System.out.println(person);
}
6、删除索引
DELETE /person
@Test
void testDeleteIndex(){
boolean bln = restTemplate.indexOps(IndexCoordinates.of("person")).delete();
System.out.println(bln);
}
7、查询所有
GET /person/_search
8、复杂查询
先插入三条数据
查询 年龄 > 20 且 姓名带“张”的
GET /person/_search
{
“query”: {
“bool”: {
“must”: [
{“range”: {
“age”: {
“gte”: 20
}
}},
{“match”: {
“name”: “张”
}}
]
}
}
}
@Test
void testSearch(){
//1、创建一个原生检索。代表能使用原生的DSL进行检索
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
boolQuery.must(QueryBuilders.rangeQuery("age").gte(20L));
boolQuery.must(QueryBuilders.matchQuery("name","张"));
//========原生检索: 利用QueryBuilders 创建一个检索条件=======
Query query = new NativeSearchQuery(boolQuery);
//2、检索命中的记录信息
SearchHits<Person> hits = restTemplate.search(query, Person.class, IndexCoordinates.of("person"));
System.out.println("检索结果:"+hits);
for (SearchHit<Person> hit : hits.getSearchHits()) {
Person person = hit.getContent();
System.out.println(person);
}
}
Spring Data ES
@EnableElasticsearchRepositories : 开启es 自动仓库功能;
1、写Bean
@Document(indexName = "person") //这是一个文档
public class Person {
@Id //主键
private Long id;
@Field(value = "name",type = FieldType.Text) //文本字段能全文检索
private String name;
@Field(value = "age",type = FieldType.Integer)
private Integer age;
}
2、写接口
@Repository
public interface PersonRepository extends CrudRepository<Person,Long> {
}
3、效果
1、项目启动自动创建出这个索引
2、索引的映射关系都是我们指定好的
3、crud就会简单
4、使用
@Autowired
PersonRepository personRepository;
@Test
void testCrud(){
List<Person> list = Arrays.asList(
new Person(1L, "张三", 18),
new Person(2L, "张四", 19),
new Person(3L, "李六", 20)
);
personRepository.saveAll(list);
System.out.println("save success");
Iterable<Person> all = personRepository.findAll();
all.forEach(item->{
System.out.println(item);
});
}
查询
只需要在PersonRepository接口中增加方法,此时IDEA会有非常智能的提示
@Repository
public interface PersonRepository extends CrudRepository<Person,Long> {
List<Person> findAllByAgeGreaterThanEqual(Integer age);
}
@Test
void testQuery(){
List<Person> all = personRepository.findAllByAgeGreaterThanEqual(19);
all.forEach(item->{
System.out.println(item);
});
}
5、ES如何起名参照文档
如果spring data提供的不能满足你的需求,还可以自定义
中文分词
安装;
- 下载对应版本的分词器
Releases · medcl/elasticsearch-analysis-ik (github.com) - 上传给es的 /usr/share/elasticsearch/plugins 目录
- 解压
unzip elasticsearch-analysis-ik-7.13.4.zip -d ik/ - 复制
#把外面的复制到容器内部
docker cp ik d69f3b005b4b:/usr/share/elasticsearch/plugins/
#把容器内部复制到外面(相反)
docker cp d69f3b005b4b:/usr/share/elasticsearch/plugins/ ik