索引库操作
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;
@Test
void testInit(){
System.out.println(client);
}
//执行前初始化
@BeforeEach
void setUp(){
this.client=new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://xxx.xxx.xxx.xxx:9200")
//HttpHost.create("http://xxx.xxx.xxx.xxx:9200") 集群时添加更多的地址
));
}
//销毁
@AfterEach
void 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" +
"}";
}
@Test
void createHotelIndex() throws IOException {
//1.创建Request对象
CreateIndexRequest request = new CreateIndexRequest("hotel");
//2.准备请求的参数
request.source(MAPPING_TEMPLATE, XContentType.JSON);
//3.发送请求
client.indices().create(request, RequestOptions.DEFAULT);
}
运行后可以查询到对应的索引库
删除和判断索引库
@Test
void testDeleteHotelIndex() throws IOException {
//1.创建Request对象
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
//2.发送请求
client.indices().delete(request, RequestOptions.DEFAULT);
}
@Test
void 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;
@Autowired
private IHotelService hotelService;
@Test
void 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);
}
//执行前初始化
@BeforeEach
void setUp(){
this.client=new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://119.91.147.100:9200")
//HttpHost.create("http://xxx.xxx.xxx.xxx:9200") 集群时添加更多的地址
));
}
//销毁
@AfterEach
void tearDown() throws IOException {
this.client.close();
}
}
这里使用给定的项目代码在数据库配置中有错误
改成如下
url: jdbc:mysql://localhost:3306/heima?allowPublicKeyRetrieval=true&useSSL=false
成功弄执行后便可查询到
查询文档
@Test
void testGetDocumentById() throws IOException {
//1.准备request
GetRequest 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);
}
成功查询得到
更新文档
@Test
void testUpdate() throws IOException {
//1.准备request
UpdateRequest request = new UpdateRequest("hotel", "61083");
//2.准备请求参数
request.doc(
"price","961",
"starName","三转"
);
//3.发送请求
client.update(request,RequestOptions.DEFAULT);
}
删除文档
@Test
void testDeleteDocument() throws IOException {
//1.准备request
DeleteRequest request = new DeleteRequest("hotel", "61083");
//2.发送请求
client.delete(request,RequestOptions.DEFAULT);
}
总结
批量导入文档
@Test
void testBulkRequest() throws IOException {
//批量查询酒店数据
List<Hotel> hotels = hotelService.list();
//1.创建request
BulkRequest request = new BulkRequest();
//2.准备参数,添加多个新增的request
for (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条数据