目录
mapping是对索引库中文档的约束,常见的mapping属性包括:
type:字段数据类型,常见的简单类型有:
字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
数值:long、integer、short、byte、double、float、
布尔:boolean
日期:date
对象:object
index:是否创建索引,默认为true
analyzer:使用哪种分词器
properties:该字段的子字段
一、索引库操作
创建索引库和映射
为字段规定约束条件
PUT /索引库名称
{
"mappings": {
"properties": {
"字段名":{
"type": "text",
"analyzer": "ik_smart"
},
"字段名2":{
"type": "keyword",
"index": "false"
}
}
}
}
通过以下语句创建名为jungle_study的索引
PUT /jungle_study
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"name": {
"type": "text",
"analyzer": "ik_max_word",
"copy_to": "all"
},
"location": {
"type": "geo_point"
},
"pic": {
"type": "keyword",
"index": false
},
"all": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
springboot中引入依赖看第三部分
对应Java代码:
springboot中注入RestHighLevelClient Bean对象:
@Configuration
public class ESConfig {
@Bean
public RestHighLevelClient client(){
return new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://172.20.3.28:9200")
));
}
}
注入Bean
@Resource
private RestHighLevelClient client;
发送请求创建对应索引库,MAPPING_TEMPLATE为上面创建索引库的请求参数部分,即{ }部分
// 1.创建Request对象
CreateIndexRequest request = new CreateIndexRequest("jungle_study");
// 2.准备请求的参数:DSL语句
request.source(MAPPING_TEMPLATE, XContentType.JSON);
// 3.发送请求
client.indices().create(request, RequestOptions.DEFAULT);
请求方式:PUT
请求路径:/jungle_study
请求参数:
{
······
}text(可分词的文本)、keyword(精确值)、index为false(不创建索引不参与搜索)、analyzer(分词器)、properties(该字段的子字段)
几个特殊字段说明:
location:地理坐标,里面包含精度、纬度
all:一个组合字段,其目的是将多字段的值 利用copy_to合并,实现多个提供给用户搜索
ES中支持两种地理坐标数据类型:
geo_point : 由纬度(latitude)和经度(longitude)确定的一个点。例如:"32.8752345,120.2981576"
geo_shape : 有多个ge0_points组成的复杂几何图形。例如一条直线,"LINESTRING(-77.0365338.897676,-77.00905138.889939)"
字段拷贝可以使用copy_to属性将当前字段拷贝到指定字段。示例:
"a11":{
"type":"text",//类型
"analyzer":"ik_max_word" //分词器},
"brand":{
"type":"keyword",
"copy_to":"all"
}
查询索引库
GET /索引库名
#示例:
GET /jungle_study
Java中为判断是否存在:
GetIndexRequest request = new GetIndexRequest("hotel");
client.indices().exists(request, RequestOptions.DEFAULT);
修改索引库
倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引。
一旦创建,无法修改mapping中已有的字段 ,允许添加新的字段到mapping中,因为不会对倒排索引产生影响,在下面语句中没有该字段才能修改成功,相当于添加新字段字段。注意以下语句于创建索引不同的是多了_mapping请求路径,和少了“mapping”:{}
PUT /索引库名/_mapping
{
"properties": {
"新字段名":{
"type": "integer"
}
}
}
PUT /jungle_study/_mapping
{
"properties":{
"age":{
"type":"integer",
"index":false
}
}
}
删除索引库
DELETE /索引库名
DELETE /jungle_study
Java实现:
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
client.indices().delete(request, RequestOptions.DEFAULT);
二、文档操作
新增文档
POST /索引库名/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
"字段3": {
"子属性1": "值3",
"子属性2": "值4"
}
}
POST /jungle/_doc/1001
{
"info": "今天有个Bug",
"email": "example@qq.com",
"name": {
"firstName": "钱",
"lastName": "学森"
}
}
Java实现 :
IndexRequest request = new IndexRequest("索引库名").id(数据库中查出数据的id作为文档id);
request.source(实体转json, XContentType.JSON);
client.index(request, RequestOptions.DEFAULT);//发送请求创建文件
查询文档
GET /索引库名称/_doc/id
GET /jungle/_doc/1
删除文档
DELETE /{索引库名}/_doc/id值
# 根据id删除数据
DELETE /heima/_doc/1
Java实现:
DeleteRequest request = new DeleteRequest("索引库名", "文档id");
client.delete(request, RequestOptions.DEFAULT);
修改文档
修改有两种方式:
全量修改:直接覆盖原来的文档(先删除原来的再新增当前的,如果文档id不存在,则删除失败仍然会新增)
增量修改:修改文档中的部分字段,只在这些字段基础上改,而不会所有字段修改
全量修改:
PUT /索引库名/_doc/文档id
{
"字段1": "值1",
"字段2": "值2"
}
增量修改:
POST /索引库名/_update/文档id
{
"doc": {
"字段名": "新的值",
}
}
java中:
UpdateRequest request = new UpdateRequest("索引库名", "文档id");
request.doc(
"price", "952",
"starName", "四钻"
);
client.update(request, RequestOptions.DEFAULT);
三、在Java中使用RestHighLevelClient
在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。
从下图中可以看出SpringBoot默认管理的ES版本是7.6.2,我们需要修改他的版本与我们自己的ES服务的版本一致,我的版本是7.17.16版本
将其复制出来,在自己项目的<properties>中改成想要的版本:
<properties>
<elasticsearch.version>7.17.16</elasticsearch.version>
</properties>
引依赖:
<!--es的RestHighLevelClient-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
jackson:一个 JSON 对象映射库,可实现应用程序类与 Elasticsearch API 的无缝集成。
生成测试类方法快捷键: ALT+ Insert
运行测试方法之前的操作:
@BeforeEach
void setUp() {
this.client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://172.30.171.205:9200")
));
}
运行测试方法之后的操作:
@AfterEach
void tearDown() throws IOException {
this.client.close();
}
根据自己的数据库表结构,定义索引库,Java中定义字符串常量:
public static final String MAPPING_TEMPLATE ="{\n" +
" \"mappings\": {\n" +
" \"properties\": {\n" +
" \"id\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"name\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"price\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"brand\":{\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"location\":{\n" +
" \"type\": \"geo_point\"\n" +
" },\n" +
" \"all\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
DSL语句:
PUT /clothes
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"name":{
"type": "text",
"analyzer": "ik_max_word",
"copy_to": "all"
},
"price":{
"type": "integer"
},
"brand":{
"type": "keyword",
"copy_to": "all"
},
"location":{
"type": "geo_point"
},
"all":{
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
Java中的创建索引库的代码:
@Test
void contextLoads() throws IOException {
// 1.创建Request对象
CreateIndexRequest request = new CreateIndexRequest("jungle_study");
// 2.准备请求的参数:DSL语句
request.source(MAPPING_TEMPLATE, XContentType.JSON);
// 3.发送请求
client.indices().create(request, RequestOptions.DEFAULT);
}
更多API在官方文档中: