索引库操作
mapping属性
mapping是对文档的约束,常见约束属性包括:
创建索引库
#创建索引库
PUT /heima
{"mappings": {"properties": {"info":{"type": "text","analyzer": "ik_smart"},"email":{"type": "keyword","index": false},"name":{"type": "object","properties": {"firstName":{"type":"keyword"},"lastName":{"type":"keyword"}}}}}
}
如下所示,成功创建一个索引库
查询,删除,修改索引库
在es中不允许修改索引库,但可以添加新的字段
#添加新字段
PUT /heima/_mapping
{"properties":{"age":{"type":"integer"}}
}
然后重新获取就有新的字段出现了
文档操作
新增文档
在索引库插入一个规定格式的数据就像在一个数据库表里面插入一条数据。
POST /heima/_doc/1
{"info":"北岭山脚鼠鼠","email":"yhy@beiling.cn","name":{"firstName":"云","lastName":"赵"}
}
查询和删除
修改文档
有两种修改方式——全量修改
全量修改与新增文档几乎一模一样就是方法名不同
#全量修改文档PUT /heima/_doc/1
{"info":"北岭鼠鼠","email":"yhy@beiling.cn","name":{"firstName":"云","lastName":"赵"}
}
#局部修改文档字段
POST /heima/_doc/1
{"doc":{"email":"123@123.cn"}
}
RestClient操作索引库(java)
入门案例
导入Demo
创建一个名为heima的数据库运行给好的SQL文件就可以得到如下。
然后导入准备好的项目
分析数据结构
id属性较为特殊,在索引库里面是字符串,并且不分词,所以用的是keyword类型
address不参与搜索,选择index置为false.
starName使用驼峰命名法。
地理坐标较为特殊,由两个字段组成,使用一个location字段表示
有多个字段同时参与搜索,但是通常一个字段的查询效率比较高,解决方法如下,用一个all字段包含多个字段就可以根据其中一个字段搜索到多个字段的内容了。并且all字段不参与倒排索引
定义对应的Mapping映射
PUT /hotel
{"mappings": {"properties": {"id":{"type": "keyword"},"name":{"type": "text","analyzer": "ik_max_word", "copy_to": "all"},"address":{"type":"keyword","index": false},"price":{"type":"integer"},"score":{"type": "integer"},"brand":{"type": "keyword","copy_to": "all"},"city":{"type": "keyword" },"starName":{"type": "keyword"},"business":{"type": "keyword","copy_to": "all"},"location":{"type":"geo_point"},"pic":{"type":"keyword","index": false},"all":{"type": "text","analyzer": "ik_max_word"}}}
}
初始化JavaRestClient
<!--elasticsearch--><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.12.1</version></dependency>
不指定版本的话里面有子依赖会用默认7.6版本。
创建新的测试类
使用Before注解在最开始创建,之后可以直接使用。
public class HotelIndexTest {private RestHighLevelClient client;@Testvoid testInit(){System.out.println(client);}//执行前初始化@BeforeEachvoid setUp(){this.client=new RestHighLevelClient(RestClient.builder(HttpHost.create("http://xxx.xxx.xxx.xxx:9200")//HttpHost.create("http://xxx.xxx.xxx.xxx:9200") 集群时添加更多的地址));}//销毁@AfterEachvoid tearDown() throws IOException {this.client.close();}
}
创建索引库
准备一个实体对象静态属性
public class HotelConstants {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" +" \"address\":{\n" +" \"type\":\"keyword\",\n" +" \"index\": false\n" +" },\n" +" \"price\":{\n" +" \"type\":\"integer\"\n" +" },\n" +" \"score\":{\n" +" \"type\": \"integer\"\n" +" },\n" +" \"brand\":{\n" +" \"type\": \"keyword\",\n" +" \"copy_to\": \"all\"\n" +" },\n" +" \"city\":{\n" +" \"type\": \"keyword\" \n" +" },\n" +" \"starName\":{\n" +" \"type\": \"keyword\"\n" +" },\n" +" \"business\":{\n" +" \"type\": \"keyword\",\n" +" \"copy_to\": \"all\"\n" +" },\n" +" \"location\":{\n" +" \"type\":\"geo_point\"\n" +" },\n" +" \"pic\":{\n" +" \"type\":\"keyword\",\n" +" \"index\": false\n" +" },\n" +" \"all\":{\n" +" \"type\": \"text\",\n" +" \"analyzer\": \"ik_max_word\"\n" +" }\n" +" }\n" +" }\n" +"}";
}
@Testvoid createHotelIndex() throws IOException {//1.创建Request对象CreateIndexRequest request = new CreateIndexRequest("hotel");//2.准备请求的参数request.source(MAPPING_TEMPLATE, XContentType.JSON);//3.发送请求client.indices().create(request, RequestOptions.DEFAULT);}
运行后可以查询到对应的索引库
删除和判断索引库
@Testvoid testDeleteHotelIndex() throws IOException {//1.创建Request对象DeleteIndexRequest request = new DeleteIndexRequest("hotel");//2.发送请求client.indices().delete(request, RequestOptions.DEFAULT);}@Testvoid testExistsHotelIndex() throws IOException {//1.创建Request对象GetIndexRequest request = new GetIndexRequest("hotel");//2.发送请求boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);//3.输出System.out.println(exists?"索引库已存在":"索引库不存在");}
总结:
RestClient操作文档
初始化和上面一样
添加文档
这里将查询数据库的数据插入到索引库当中,但是索引库中的location是将两个数据拼到一起的,所以这里有两个实体类,一个对应数据库,一个对应索引库,从数据库查出来之后还要转到索引库数据类型。
然后再序列化层JSON风格的数据。
@SpringBootTest
public class HotelDocumentTest {private RestHighLevelClient client;@Autowiredprivate IHotelService hotelService;@Testvoid testAddDocument() throws IOException {//根据id查询酒店数据Hotel hotel = hotelService.getById(61083L);//转换为文档类型HotelDoc hotelDoc = new HotelDoc(hotel);//1.准备Request对象IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());//2.准备JSON文档request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);//3.发送请求client.index(request,RequestOptions.DEFAULT);}//执行前初始化@BeforeEachvoid setUp(){this.client=new RestHighLevelClient(RestClient.builder(HttpHost.create("http://119.91.147.100:9200")//HttpHost.create("http://xxx.xxx.xxx.xxx:9200") 集群时添加更多的地址));}//销毁@AfterEachvoid tearDown() throws IOException {this.client.close();}
}
这里使用给定的项目代码在数据库配置中有错误
改成如下
url: jdbc:mysql://localhost:3306/heima?allowPublicKeyRetrieval=true&useSSL=false
成功弄执行后便可查询到
查询文档
@Testvoid testGetDocumentById() throws IOException {//1.准备requestGetRequest request = new GetRequest("hotel", "61083");//2.发送请求,得到响应GetResponse response = client.get(request, RequestOptions.DEFAULT);//3.解析响应结果String json = response.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc);}
成功查询得到
更新文档
@Testvoid testUpdate() throws IOException {//1.准备requestUpdateRequest request = new UpdateRequest("hotel", "61083");//2.准备请求参数request.doc("price","961","starName","三转");//3.发送请求client.update(request,RequestOptions.DEFAULT);}
删除文档
@Testvoid testDeleteDocument() throws IOException {//1.准备requestDeleteRequest request = new DeleteRequest("hotel", "61083");//2.发送请求client.delete(request,RequestOptions.DEFAULT);}
总结
批量导入文档
@Testvoid testBulkRequest() throws IOException {//批量查询酒店数据List<Hotel> hotels = hotelService.list();//1.创建requestBulkRequest request = new BulkRequest();//2.准备参数,添加多个新增的requestfor (Hotel hotel : hotels) {//转换为文档类型HotelDoc hotelDoc = new HotelDoc(hotel);//创建新增文档的Request对象request.add(new IndexRequest("hotel").id(hotel.getId().toString()).source(JSON.toJSONString(hotelDoc),XContentType.JSON));}//3.发送请求client.bulk(request,RequestOptions.DEFAULT);}
然后可以查询得到201条数据