elasticsearch基础
ElasticSearch
Elasticsearch中的核心概念
Elasticsearch虽然是一种NoSql库,但最终的目的是存储数据、检索数据。因此很多概念与MySQL类似的。
ES中的概念 | 数据库概念 | 说明 |
---|---|---|
索引库(indices) | 数据库(Database) | ES中可以有多个索引库,就像Mysql中有多个Database一样。 |
类型(Type) | 表(table) | mysql中database可以有多个table,table用来约束数据结构。而ES中的每个索引库中只有一个类型 ,类型 中用来约束字段属性的叫做映射(mapping ),7.X之后将会被取消,取默认值:_doc |
映射(mappings) | 表的字段约束 | mysql表对字段有约束,ES中叫做映射,用来约束字段属性,包括:字段名称、数据类型等信息 |
文档(document) | 行(Row) | 存入索引库原始的数据,比如每一条商品信息,就是一个文档。对应mysql中的每行数据 |
字段/域(field) | 列(Column) | 文档中的属性,一个文档可以有多个属性。就像mysql中一行数据可以有多个列。 |
因此,我们对ES的操作,就是对索引库、类型映射、文档数据的操作:
- 索引库操作:主要包含创建索引库、查询索引库、删除索引库等
- 类型映射操作:主要是创建类型映射、查看类型映射
- 文档操作:文档的新增、修改、删除、查询
ELasticsearch的索引库操作
1.创建索引库
格式:
-
请求方式:PUT
-
请求路径:/索引库名
-
请求参数:格式:
{ "settings":{ "属性名":"属性值" } } //settings:是索引库设置,其中可以定义索引库的各种属性。
//创建user索引库 PUT /user { "mappings": { "properties": { "age":{ "type":"integer" }, "sex":{ "type": "keyword", "index": false } } } }
2.查询索引库
格式:
- 请求方式:GET
- 请求路径:/索引库名
- 请求参数:无
//查询user索引库
GET /user
3.删除索引库
格式:
- 请求方式:DELETE
- 请求路径:/索引库名
- 请求参数:无
//删除user索引库
DELETE /user
mapping映射
MySQL中有表,并且表中有对字段的约束,对应到elasticsearch中就是类型映射mapping
.
映射属性
索引库数据类型是松散的,不过也需要我们指定具体的字段及字段约束信息。而约束字段信息的就叫做映射(mapping
)
官网中的映射属性查看地址:https://www.elastic.co/guide/en/elasticsearch/reference/7.16/mapping-params.html
elasticsearch字段的映射属性该怎么选,除了字段名称外,我们一般要考虑这样几个问题:
-
数据类型是什么
通过
type
属性来定义 -
是否参与搜索
通过
index
属性来定义,默认是true -
是否需要分词
通过
analyzer
属性来定义,中文一般使用ik分词器
常见的数据类型
- String类型
- text:可分词,存储到elasticsearch时会根据分词器分成多个词条
- keyword:不可分词,数据会完整的作为一个词条
- Numerical类型
- 基本数据类型:long、interger、short、byte、double、float、half_float
- 浮点数的高精度类型:scaled_float
- Date日期类型
- Object:对象,对象不便于搜索。因此ES会把对象数据扁平化处理再存储。
创建类型映射
1.索引库存在
PUT /索引库名/_mapping
{
"properties": {
"字段名1": {
"type": "类型",
"index": true,
"analyzer": "分词器"
},
"字段名2": {
"type": "类型",
"index": true,
"analyzer": "分词器"
},
...
}
}
2.索引库不存在
PUT /索引库名
{
"mappings":{
"properties": {
"字段名1": {
"type": "类型",
"index": true,
"analyzer": "分词器"
},
"字段名2": {
"type": "类型",
"index": true,
"analyzer": "分词器"
},
...
}
}
}
查看映射关系
语法:
GET /索引库名/_mapping
Document文档的操作
新增文档
新增文档自动生成id
语法:
POST /{索引库名}/_doc
{
"key":"value"
}
新增文档自动指定id
语法:
POST /{索引库名}/_doc/{id}
{
"key":"value"
}
POST 新增文档时:如果指定了id,并且id在索引库不存在,直接存入索引库;如果id已经存在,则执行修改
查询文档
根据id查询
语法:
GET /{索引库名称}/_doc/{id}
词条查询
语法:
GET /{索引库}/_search
{
"query": {
"term": {
"field字段": {
"value": "查询的关键词"
}
}
}
}
全文查询
语法:
GET /{索引库}/_search
{
"query": {
"match": {
"查询的字段":"查询关键词"
}
}
}
查询所有的文档
语法:
GET /{索引库}/_search
{
"query": {
"match_all": {}
}
}
修改文档
把新增的请求方式改为PUT,就是修改了。不过修改必须指定id
- id对应的文档存在,则修改
- id对应的文档不存在,则新增
删除文档
删除使用DELETE请求,同样,需要根据id进行删除:
语法:
DELETE /索引库名/类型名/id值
DELETE /user/_doc/10
Java API操作elasticsearch
maven依赖:
<!--elastic客户端-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.12.1</version>
</dependency>
实体类:
@Data //使用lombok插件
@AllArgsConstructor
public class User {
private Long id;
private String name; //姓名
private Integer age; //年龄
private String gender; //性别
private String note; //备注
}
与ES建立连接,ES提供了一个客户端RestHighLevelClient。
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
//集群下可以添加多个
new HttpHost("localhost", 9200, "http"),
new HttpHost("localhost", 9201, "http")));
public class ElasticSearchTest {
private RestHighLevelClient client;
@Before
//建立连接
public void init(){
client = new RestHighLevelClient(
RestClient.builder(new HttpHost("192.168.10.128",9200,"http"))
);
}
//测试
...
@After
//关闭连接
public void close() throws IOException {
client.close();
}
}
创建索引库及映射
1.创建CreateIndexRequest对象,并指定索引库名称
2.指定settings配置
3.指定mapping配置
4.发起请求,得到响应
@Test
//创建索引库
public void testCreateIndex() throws IOException {
//1.创建CreateIndexRequest请求,和索引库名称user
CreateIndexRequest request = new CreateIndexRequest("user");
//2.配置settings信息
request.settings(Settings.builder()
.put("index.number_of_shards",3)
.put("index.number_of_replicas",1)
);
//3.配置mapping信息
request.mapping(
"{\n" +
" \"properties\": {\n" +
" \"id\": {\n" +
" \"type\": \"long\"\n" +
" },\n" +
" \"name\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"age\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"gender\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"note\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" }\n" +
" }\n" +
" }",
XContentType.JSON
);
//4.发送请求,拿到响应
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
System.out.println("response:"+response.isAcknowledged());
}
文档操作
新增/修改文档
- 准备文档数据
- 创建IndexRequest对象,并指定索引库名称
- 指定新增的数据的id
- 将新增的文档数据变成JSON格式
- 将JSON数据添加到IndexRequest中
- 发起请求,得到结果
public void testAddDocument() throws IOException {
//准备文档数据
User user = new User(110L, "李四", 18, "男", "程序员");
//创建indexRequest对象,并指定索引对象
IndexRequest request = new IndexRequest("user");
//指定新增数据的id
request.id(user.getId().toString());
//将文档数据转化为json格式
String userJson = JSON.toJSONString(user);
//将数据添加到request中
request.source(userJson,XContentType.JSON);
//发起请求,得到结果
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println("response:" + response.getResult());
}
根据id查询文档
- 创建GetRequest 对象,并指定索引库名称、文档ID
- 发起请求,得到结果
- 从结果中得到source,是json字符串
- 将JSON反序列化为对象
public void getDocumentById() throws IOException {
//创建getRequest对象
GetRequest request = new GetRequest("user", "110");
//发送请求,拿到结果
GetResponse response = client.get(request, RequestOptions.DEFAULT);
String source = response.getSourceAsString();
User user = JSON.parseObject(source, User.class);
System.out.println(user);
}
删除文档
- 创建DeleteRequest对象,指定索引库名称、文档ID
- 发起请求
public void deleteDocument() throws IOException {
//创建deleteRequest对象
DeleteRequest request = new DeleteRequest("user", "110");
//发送请求
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println("response:" + response.getResult());
}
批量处理
一个BulkRequest可以在一次请求中执行多个 新增、更新、删除请求。
所以,BulkRequest就是把多个其它增、删、改请求整合,然后一起发送到ES来执行。
我们拿批量新增来举例,步骤如下:
- 从数据库查询文档数据
- 创建BulkRequest对象
- 创建多个IndexRequest对象,组织文档数据,并添加到BulkRequest中
- 发起请求
public void bulkAddDocument() throws IOException {
List<User> users = Arrays.asList(
new User(1L, "Rose", 18, "1", "我是Rose"),
new User(2L, "Jack", 38, "1", "我是Jack"),
new User(3L, "小红", 23, "0", "我是小红"),
new User(4L, "小明", 20, "1", "我是小明")
);
BulkRequest bulkRequest = new BulkRequest();
for (User user : users) {
bulkRequest.add(new IndexRequest("user")
.id(user.getId().toString())
.source(JSON.toJSONString(user),XContentType.JSON));
}
//发送请求
BulkResponse responses = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println("response:"+responses.status());
}