目录
1:ES的使用(DSL创建索引库-相当于表)
这些都是在kibana的开发者工具中测试的curl的DSL语句,因为ES是RESTFul风格的,这里使用kibana工具测试
1.1:什么是索引库
这里的索引库就是相当于mysql的表创建
es01 就是相当于mysql数据库中的表,
mapping:就是对表中字段的映射,
properties:就是包含各个字段,
type:设置字段类型,包含字符类型、数字类型、布尔类型等
analyzer:设置字段的分词,创建倒排索引,便于搜索,只是用text类型
1.2:索引库的增删改查使用
索引库相当于创建了表,设置了各个字段的属性,索引。这是对于mysql来说的,便于理解
下边还有对索引库的数据的增删改查,就会看的更加清楚
#创建索引库名字 /es01
#age字段 不用创建分词
#info字段 ik_smart创建分词
#email字段 keyword 不用创建分词
#name字段 前置名字 后置名字
put /es01
{
"mappings":{
"properties":{
"age":{
"type": "integer"
},
"info":{
"type":"text",
"analyzer":"ik_smart"
},
"email":{
"type":"keyword",
"index":false
},
"name":{
"type":"object",
"properties":{
"firstName":{
"type":"keyword",
"index":false
},
"lastName":{
"type":"keyword"
}
}
}
}
}
}
#查询索引库
get /es01
#修改索引库 索引库只能添加新的字段
#添加性别字段
PUT /es01/_mapping
{
"properties":{
"sex":{
"type": "long"
}
}
}
#删除索引库
delete /es01
2:ES的使用(DSL操作文档-相当于数据)
2.1:什么是文档
文档就是数据,对比mysql的话,就是表中添加数据,但是这里添加的数据是json
2.2:文档的增删改查
对文档增删改查就相当于在mysql表中对于数据的增删改查,便于理解
#添加文档(数据)到索引库(表)
# PUT /索引库名字/_doc/文档id
PUT /es01/_doc/4
{
"age":11,
"email":"12345672@qq.com",
"info":"小米手机充电器是新鸟传媒公司白嫖的,哦买嘎。好用极了!",
"name":{
"firstName":"孙",
"lastName":"悟空44"
},
"sex":2
}
#查询文档(数据)
get /es01/_doc/4
#删除文档(数据)
delete /es01/_doc/1
#修改文档全部字段
PUT /es01/_doc/4
{
"age":11,
"email":"12345672@qq.com",
"info":"小米手机充电器是新鸟传媒公司白嫖的,哦买嘎。好用极了!",
"name":{
"firstName":"孙",
"lastName":"悟空44"
},
"sex":2
}
#修改部分字段
PUT /es01/_doc/4
{
"name":{
"firstName":"孙",
"lastName":"悟空444"
}
}
3:java代码开发
因为前边都是使用kibana的控制台来进行的测试,方便我们理解具体的机制,不是代码。我们在实际的开发过程中是使用代码进行开的,下边介绍Java代码怎么进行开发
首先创建表,添加数据,然后使用Java代码创建索引,对索引进行增删改查,在索引中添加数据,进行增删改查。
3.1:准备工作
1:创建数据表,添加数据,创建springboot项目,生成增删改查代码
DROP TABLE IF EXISTS `tb_hotel`;
CREATE TABLE `tb_hotel` (
`id` bigint(20) NOT NULL COMMENT '酒店id',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店名称',
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店地址',
`price` int(10) NOT NULL COMMENT '酒店价格',
`score` int(2) NOT NULL COMMENT '酒店评分',
`brand` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店品牌',
`city` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '所在城市',
`star_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店星级,1星到5星,1钻到5钻',
`business` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商圈',
`latitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '纬度',
`longitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '经度',
`pic` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店图片',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
-- ----------------------------
INSERT INTO `tb_hotel` VALUES (36934, '7天连锁酒店(上海宝山路地铁站店)', '静安交通路40号', 336, 37, '7天酒店', '上海', '二钻', '四川北路商业区', '31.251433', '121.47522', 'https://m.tuniucdn.com/fb2/t1/G1/M00/3E/40/Cii9EVkyLrKIXo1vAAHgrxo_pUcAALcKQLD688AAeDH564_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38609, '速8酒店(上海赤峰路店)', '广灵二路126号', 249, 35, '速8', '上海', '二钻', '四川北路商业区', '31.282444', '121.479385', 'https://m.tuniucdn.com/fb2/t1/G2/M00/DF/96/Cii-TFkx0ImIQZeiAAITil0LM7cAALCYwKXHQ4AAhOi377_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38665, '速8酒店上海中山北路兰田路店', '兰田路38号', 226, 35, '速8', '上海', '二钻', '长风公园地区', '31.244288', '121.422419', 'https://m.tuniucdn.com/fb2/t1/G2/M00/EF/86/Cii-Tlk2mV2IMZ-_AAEucgG3dx4AALaawEjiycAAS6K083_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38812, '7天连锁酒店(上海漕溪路地铁站店)', '徐汇龙华西路315弄58号', 298, 37, '7天酒店', '上海', '二钻', '八万人体育场地区', '31.174377', '121.442875', 'https://m.tuniucdn.com/fb2/t1/G2/M00/E0/0E/Cii-TlkyIr2IEWNoAAHQYv7i5CkAALD-QP2iJwAAdB6245_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (39106, '7天连锁酒店(上海莘庄地铁站店)', '闵行莘庄镇七莘路299号', 348, 41, '7天酒店', '上海', '二钻', '莘庄工业区', '31.113812', '121.375869', 'https://m.tuniucdn.com/fb2/t1/G2/M00/D8/11/Cii-T1ku2zGIGR7uAAF1NYY9clwAAKxZAHO8HgAAXVN368_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (39141, '7天连锁酒店(上海五角场复旦同济大学店)', '杨浦国权路315号', 349, 38, '7天酒店', '上海', '二钻', '江湾、五角场商业区', '31.290057', '121.508804', 'https://m.tuniucdn.com/fb2/t1/G2/M00/C7/E3/Cii-T1knFXCIJzNYAAFB8-uFNAEAAKYkQPcw1IAAUIL012_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (45845, '上海西藏大厦万怡酒店', '虹桥路100号', 589, 45, '万怡', '上海', '四钻', '徐家汇地区', '31.192714', '121.434717', 'https://m.tuniucdn.com/fb3/s1/2n9c/48GNb9GZpJDCejVAcQHYWwYyU8T_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (45870, '上海临港豪生大酒店', '新元南路555号', 896, 45, '豪生', '上海', '四星级', '滴水湖临港地区', '30.871729', '121.81959', 'https://m.tuniucdn.com/fb3/s1/2n9c/2F5HoQvBgypoDUE46752ppnQaTqs_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (46829, '上海浦西万怡酒店', '恒丰路338号', 726, 46, '万怡', '上海', '四钻', '上海火车站地区', '31.242977', '121.455864', 'https://m.tuniucdn.com/fb3/s1/2n9c/x87VCoyaR8cTuYFZmKHe8VC6Wk1_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (47066, '上海浦东东站华美达酒店', '施新路958号', 408, 46, '华美达', '上海', '四钻', '浦东机场核心区', '31.147989', '121.759199', 'https://m.tuniucdn.com/fb3/s1/2n9c/2pNujAVaQbXACzkHp8bQMm6zqwhp_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (47478, '速8酒店(上海松江中心店)', '松江荣乐东路677号', 428, 35, '速8', '上海', '二钻', '佘山、松江大学城', '31.016712', '121.261606', 'https://m.tuniucdn.com/filebroker/cdn/res/07/36/073662e1718fccefb7130a9da44ddf5c_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (56201, '上海齐鲁万怡大酒店', '东方路838号', 873, 44, '万怡', '上海', '四星级', '浦东陆家嘴金融贸易区', '31.226031', '121.525801', 'https://m.tuniucdn.com/fb2/t1/G6/M00/52/B6/Cii-TF3eXKeIJeN7AASiKHbTtx4AAGRegDSBzMABKJA111_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (56214, '上海浦东华美达大酒店', '新金桥路18号', 830, 45, '华美达', '上海', '四星级', '浦东金桥地区', '31.244916', '121.590752', 'https://m.tuniucdn.com/fb3/s1/2n9c/3jtXiuMKZEXJAuKuAkc47yLCjUBt_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (56227, '上海圣淘沙万怡酒店', '南桥镇南桥路1号', 899, 45, '万怡', '上海', '四星级', '奉贤开发区', '30.910917', '121.456525', 'https://m.tuniucdn.com/fb2/t1/G6/M00/52/B9/Cii-U13eXSiIdJjXAARSA6FywFYAAGRnwHvy1AABFIb158_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (56392, '上海银星皇冠假日酒店', '番禺路400号', 809, 47, '皇冠假日', '上海', '五星级', '徐家汇地区', '31.202768', '121.429524', 'https://m.tuniucdn.com/fb3/s1/2n9c/37ucQ38K3UFdcRqntJ8M5dt884HR_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (56852, '上海财大豪生大酒店', '武东路188号', 592, 46, '豪生', '上海', '五钻', '江湾/五角场商业区', '31.304182', '121.492936', 'https://m.tuniucdn.com/fb3/s1/2n9c/2jGHezLZvPZqC9cBGesbP5vAhCXi_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (56912, '上海华凯华美达广场酒店', '月华路9号', 747, 40, '华美达', '上海', '四钻', '奉贤开发区', '30.814382', '121.464521', 'https://m.tuniucdn.com/fb3/s1/2n9c/45iaCNCuZavJTxwTLskhVKzwynLD_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (56977, '上海五角场华美达大酒店', '黄兴路1888号', 499, 40, '华美达', '上海', '三钻', '江湾/五角场商业区', '31.292932', '121.519759', 'https://m.tuniucdn.com/fb3/s1/2n9c/26VREqAQdaGFvJdAJALVtjxcNMpL_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60214, '上海金茂君悦大酒店', '世纪大道88号(54楼办理入住)', 699, 46, '君悦', '上海', '五星级', '浦东陆家嘴金融贸易区', '31.235152', '121.506082', 'https://m.tuniucdn.com/fb3/s1/2n9c/7Azm3jvGUHuXe3eS1DrixAWVTXY_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60223, '上海希尔顿酒店', '静安华山路250号', 2688, 37, '希尔顿', '上海', '五星级', '静安寺地区', '31.219306', '121.445427', 'https://m.tuniucdn.com/filebroker/cdn/res/92/10/9210e74442aceceaf6e196d61fc3b6b1_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60359, '上海外高桥皇冠假日酒店', '杨高北路1000号', 3299, 46, '皇冠假日', '上海', '五星级', '浦东外高桥地区', '31.338944', '121.590611', 'https://m.tuniucdn.com/fb3/s1/2n9c/VcKUM9zUSiVgDhFioc6mWQoX9ES_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60363, '上海新世界丽笙大酒店', '南京西路88号', 1341, 46, '丽笙', '上海', '五星级', '人民广场地区', '31.23462', '121.47327', 'https://m.tuniucdn.com/fb3/s1/2n9c/2j31b7X3YzGkf4Li3phS6TG1mtwm_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60398, '上海复旦皇冠假日酒店', '邯郸路199号', 924, 47, '皇冠假日', '上海', '五星级', '江湾/五角场商业区', '31.295382', '121.502537', 'https://m.tuniucdn.com/fb3/s1/2n9c/2H1Gk8LHaBWZfYvR6NYYcGTvACmL_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60487, '上海外滩茂悦大酒店', '黄浦路199号', 689, 44, '君悦', '上海', '五星级', '外滩地区', '31.245409', '121.492969', 'https://m.tuniucdn.com/fb3/s1/2n9c/2Swp2h1fdj9zCUKsk63BQvVgKLTo_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60522, '上海嘉豪淮海国际豪生酒店', '汾阳路1号', 425, 45, '豪生', '上海', '四钻', '淮海路/新天地地区', '31.215497', '121.456297', 'https://m.tuniucdn.com/fb3/s1/2n9c/38UBi4QYuaF8jN94CxQ7tb7tjtmZ_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60916, '上海绿地万怡酒店', '沪宜公路3101号', 328, 45, '万怡', '上海', '四钻', '嘉定新城', '31.368523', '121.258567', 'https://m.tuniucdn.com/fb3/s1/2n9c/3VLwG9tTQQnp3M3MTeMTdx9nas9B_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60922, '上海虹桥祥源希尔顿酒店', '红松东路1116号', 1108, 45, '希尔顿', '上海', '五钻', '虹桥地区', '31.18746', '121.395312', 'https://m.tuniucdn.com/fb3/s1/2n9c/tQRqDTFkHnHzMZiDKjcGV81ekvc_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (60935, '上海虹口三至喜来登酒店', '四平路59号', 1899, 46, '喜来登', '上海', '五星级', '四川北路商业区', '31.2579', '121.487954', 'https://m.tuniucdn.com/fb3/s1/2n9c/3C3gxLxLjVwnkxJwJm8rd3f38kcd_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (61075, '上海雅居乐万豪酒店', '西藏中路555号', 1152, 46, '万豪', '上海', '五钻', '人民广场地区', '31.236681', '121.473529', 'https://m.tuniucdn.com/fb3/s1/2n9c/3FoT16PkXavKsssvktVvVq5Si6Cr_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (61083, '上海滴水湖皇冠假日酒店', '自由贸易试验区临港新片区南岛1号', 971, 44, '皇冠假日', '上海', '五钻', '滴水湖临港地区', '30.890867', '121.937241', 'https://m.tuniucdn.com/fb3/s1/2n9c/312e971Rnj9qFyR3pPv4bTtpj1hX_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (309208, '北京王府井希尔顿酒店', '王府井东街8号', 1679, 46, '希尔顿', '北京', '五钻', '天安门/王府井地区', '39.914539', '116.413392', 'https://m.tuniucdn.com/fb2/t1/G6/M00/52/10/Cii-TF3ePt2IX9UEAALb6VYBSmoAAGKMgGsuW8AAtwB147_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (394559, '北京东方君悦大酒店', '长安街1号东方广场', 686, 45, '君悦', '北京', '五星级', '天安门/王府井地区', '39.909635', '116.414621', 'https://m.tuniucdn.com/fb3/s1/2n9c/3mFqcNSh7eEo9yc3Rw2P5HDNTdDe_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (394617, '北京宝辰饭店', '建国门内大街甲18号', 418, 44, '豪生', '北京', '四星级', '北京站/建国门地区', '39.905768', '116.428153', 'https://m.tuniucdn.com/fb3/s1/2n9c/NEYa6EfDHuhhb19Ct85WBbkKHZU_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (394796, '北京新云南皇冠假日酒店', '东北三环西坝河太阳宫桥东北角云南大厦', 485, 46, '皇冠假日', '北京', '五星级', '国展中心地区', '39.972409', '116.434698', 'https://m.tuniucdn.com/fb3/s1/2n9c/dfP8K782eTsohQWSRdkd7St9LA2_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (395434, '北京希尔顿酒店', '东三环北路东方路1号', 350, 45, '希尔顿', '北京', '五星级', '燕莎/朝阳公园商业区', '39.952703', '116.462387', 'https://m.tuniucdn.com/fb3/s1/2n9c/3fwNbKGhk6XCrkdVyxwhC5uGpLVy_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (395702, '北京首都机场希尔顿酒店', '首都机场3号航站楼三经路1号', 222, 46, '希尔顿', '北京', '五钻', '首都机场/新国展地区', '40.048969', '116.619566', 'https://m.tuniucdn.com/fb2/t1/G6/M00/52/10/Cii-U13ePtuIMRSjAAFZ58NGQrMAAGKMgADZ1QAAVn_167_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (395787, '北京海航大厦万豪酒店', '霄云路甲26号', 1302, 46, '万豪', '北京', '五钻', '燕莎/朝阳公园商业区', '39.959861', '116.467363', 'https://m.tuniucdn.com/fb3/s1/2n9c/3zFiWi2C9SmbcQwCZgJFQC9ahvs5_w200_h200_c1_t0.jpg');
2:使用kibana的DSL语句创建hotel索引
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"
}
}
}
}
#获取索引数据
get /hotel
#删除索引
delete /hotel
3.2:代码操作索引(也就是表的增删改查)
1:导入依赖的jar
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- 8.X版本弃用了的ES的Java REST Client-->
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.11.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
2:配置ElasticsearchClient的bean
@Configuration
public class EsConfig {
/**
* 创建ElasticsearchClient的bean
* @return
*/
@Bean
public ElasticsearchClient elasticsearchClient(){
String serverUrl = "http://172.16.35.136:9200";
// 创建低级客户端 low-level client
RestClient restClient = RestClient.builder(HttpHost.create(serverUrl)).build();
//使用Jackson映射器创建传输
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
//并创建API客户端
return new ElasticsearchClient(transport);
}
}
3:启动项目需要配置SpringBootApplication的exclude属性,否则报错
@MapperScan(value = "com.example.elasticsearch_1.mapper")
//这里需要配置exclude 否则出现jar冲突 报错
@SpringBootApplication(exclude = org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchClientAutoConfiguration.class )
public class ElasticSearch1Application {
public static void main(String[] args) {
SpringApplication.run(ElasticSearch1Application.class, args);
}
}
4:测试代码测试索引的增删改查
@SpringBootTest
class 索引库操作Demo {
//并创建API客户端
ElasticsearchClient esClient = null;
private static final String hotel_index = "{\n" +
" \"mappings\":{\n" +
" \n" +
" \"properties\":{\n" +
" \n" +
" \"id\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \n" +
" \"name\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\":\"ik_max_word\",\n" +
" \"copy_to\":\"all\"\n" +
" },\n" +
" \n" +
" \"address\":{\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" },\n" +
" \n" +
" \n" +
" \"price\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"score\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \n" +
" \"brand\":{\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\":\"all\"\n" +
" },\n" +
" \"city\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \n" +
" \"starName\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"business\":{\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\":\"all\"\n" +
"\n" +
" },\n" +
" \n" +
" \"location\":{\n" +
" \"type\": \"geo_point\"\n" +
" },\n" +
" \n" +
" \"pic\":{\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" },\n" +
" \n" +
" \"all\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\":\"ik_max_word\"\n" +
" }\n" +
" \n" +
" \n" +
" }\n" +
" }\n" +
"}";
@BeforeEach
void es1Test() {
// URL and API key
String serverUrl = "http://172.16.35.136:9200";
String apiKey = "VnVhQ2ZHY0JDZGJrU...";
// 创建低级客户端 low-level client
RestClient restClient = RestClient
.builder(HttpHost.create(serverUrl))
// .setDefaultHeaders(new Header[]{
// new BasicHeader("Authorization", "ApiKey " + apiKey)
// })
.build();
System.out.println(restClient);
//使用Jackson映射器创建传输
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
//并创建API客户端
this.esClient = new ElasticsearchClient(transport);
System.out.println(esClient);
}
//创建索引库
@Test
void creatHotelIndex() throws IOException {
System.out.println(esClient);
InputStream inputStream = new FileInputStream("/Users/huyiju/work/ideawork2/SpringBootProjects/ElasticSearch_1/src/main/resources/hotel.json");
CreateIndexResponse createIndexResponse = esClient.indices().create(
new CreateIndexRequest.Builder()
//创建索引
.index("hotel")
//创建索引内容 外部文件
//.withJson(inputStream)
//创建索引内容 String字符串的json创建
.withJson(new StringReader(hotel_index))
.build()
);
if (createIndexResponse.acknowledged()) {
System.out.println("创建hotel索引成功");
} else {
System.out.println("创建hotel索引失败");
}
System.out.println(createIndexResponse.acknowledged());
}
//获取索引库 GetIndexResponse
@Test
void getHotelIndex() throws IOException {
System.out.println(esClient);
GetIndexResponse getIndexResponse = esClient.indices().get(
new GetIndexRequest.Builder().index("hotel").build()
);
Map<String, IndexState> result = getIndexResponse.result();
System.out.println(result.get("hotel"));
}
//删除索引库 DeleteIndexResponse
@Test
void deleteHotelIndex() throws IOException {
System.out.println(esClient);
DeleteIndexResponse hotel = esClient.indices().delete(
new DeleteIndexRequest.Builder().index("hotel")
.build()
);
System.out.println("删除索引:" + hotel.acknowledged());
}
//判断索引库是否存在
@Test
void isHotelIndex() throws IOException {
System.out.println(esClient);
BooleanResponse hotel = esClient.indices().exists(new ExistsRequest.Builder().index("hotel").build());
System.out.println("hotel是否存在:" + hotel.value());
}
//判断索引库是否存在
@Test
void json() {
System.out.println("hotel是否存在:" + hotel_index);
}
}
3.3:代码操作文档(也就是数据的增删改查)
@SpringBootTest
class 文档操作Demo {
@Autowired
TbHotelServiceImpl tbHotelService;
@Autowired
ElasticsearchClient elasticsearchClient;
//添加数据
@Test
void addDocument() throws IOException {
//数据库查询到一条数据
TbHotel hotel = tbHotelService.getById(36934L);
TbHotelDoc hotelDoc=new TbHotelDoc(hotel);
System.out.println(hotelDoc);
//数据插入ES
IndexRequest indexRequest=new IndexRequest.Builder<TbHotelDoc>()
.id("11")
.index("hotel")
.document(hotelDoc).build();
elasticsearchClient.index(indexRequest);
}
//批量添加数据
@Test
void addAllDocument() throws IOException {
//查询所有数据
List<TbHotel> list = tbHotelService.list();
System.out.println("list:"+list.size());
//将数据添加到ES中
BulkRequest.Builder builder = new BulkRequest.Builder();
for (TbHotel hotel : list) {
TbHotelDoc hotelDoc=new TbHotelDoc(hotel);
builder.operations(op->op.index(
idx->idx.index("hotel")
.id(hotelDoc.getId().toString())
.document(hotelDoc)
));
}
elasticsearchClient.bulk(builder.refresh(Refresh.WaitFor).build());
}
//根据id查询数据
@Test
void selectByIDDocument() throws IOException {
//GetRequest查询 查询单个
System.out.println("========查询单个GetRequest=======");
GetRequest getRequest = new GetRequest.Builder().index("hotel").id("11").build();
GetResponse<TbHotelDoc> tbHotelDocGetResponse = elasticsearchClient.get(getRequest, TbHotelDoc.class);
boolean found = tbHotelDocGetResponse.found();
if (found) {
TbHotelDoc hotelDoc = tbHotelDocGetResponse.source();
System.out.println("查询数据是:"+hotelDoc);
} else {
System.out.println("没有查询到");
}
}
//查询全部数据
//默认查询10条
@Test
void selectAlLDocument() throws IOException {
//查询全部SearchRequest
System.out.println("========查询全部SearchRequest=======");
SearchRequest searchRequest = new SearchRequest.Builder().index("hotel").build();
SearchResponse<TbHotelDoc> search = elasticsearchClient.search(searchRequest, TbHotelDoc.class);
List<Hit<TbHotelDoc>> hits = search.hits().hits();
for (Hit<TbHotelDoc> hit : hits) {
TbHotelDoc hotel = hit.source();
System.out.println(hotel);
}
}
//根据id修改数据
@Test
void updateDocument() throws IOException {
TbHotelDoc tbHotelDoc=new TbHotelDoc();
//需要更新哪个字段就赋值哪个字段
tbHotelDoc.setAddress("上海xx");
//修改这条数据
UpdateRequest<TbHotelDoc, TbHotelDoc> updateRequest = new UpdateRequest.Builder<TbHotelDoc, TbHotelDoc>()
.index("hotel")
.id("11")
.doc(tbHotelDoc)
.build();
UpdateResponse<TbHotelDoc> update = elasticsearchClient.update(updateRequest, TbHotelDoc.class);
System.out.println(update);
//直接使用接口编程修改
TbHotelDoc hotelDoc=new TbHotelDoc();
//需要更新哪个字段就赋值哪个字段
hotelDoc.setCity("xx");
elasticsearchClient.update(updateRequest1->updateRequest1
.index("hotel")
.id("11")
.doc(hotelDoc)
,TbHotelDoc.class);
}
//根据id删除数据
@Test
void deleteDocument() throws IOException {
DeleteResponse hotel = elasticsearchClient.delete(deleteRequest -> deleteRequest
.index("hotel")
.id("12"));
System.out.println(hotel);
//删除全部
// elasticsearchClient.delete(deleteRequest->deleteRequest
// .index("hotel").id("11"));
}
}
4:DSL实现复杂的查询
在上边我们只认识的对索引的创建,数据库查询数据之后,将数据插入ES,根据ID进行增删改查查,但是实际的开发过程中,因为有很多字段,不可能只对ID进行操作,需要对字段进行查询,这就有了DSL的复杂查询,类似于mysql的各种字段查询
4.1:DSL对单个字段的查询
#--------全文检索 针对type=text类型-------
#根据type=text字段进行分词,然后查询,只能有一个条件
#match 单个匹配
get /hotel/_search
{
"query":{
"match": {
"all": "外滩如家"
}
}
}
#根据type=text字段进行分词,然后查询,可以有多个条件
#multi_match 多重匹配 参与字段越多 性能越低,
#建议利用"copy_to":"all" 将多个字段合并为一个字段 类似于mysql的联合索引
get /hotel/_search
{
"query":{
"multi_match": {
"query": "外滩如家",
"fields": ["name","brand","business"]
}
}
}
#--------精确 针对type=keyword、id、数值、布尔类型 这些字段必须精确匹配------
#term 精确匹配
# city "type": "keyword" 的精确查询
# select * from tb_hotel where city="上海"
get /hotel/_search
{
"query":{
"term": {
"city": {
"value": "上海"
}
}
}
}
# score "type": "integer" 的精确查询
# select * from tb_hotel where score=35
get /hotel/_search
{
"query":{
"term": {
"score": {
"value": "35"
}
}
}
}
# score "type": "integer" 的精确查询
# select * from tb_hotel where star_name="四星级"
get /hotel/_search
{
"query":{
"term": {
"starName": {
"value": "四星级"
}
}
}
}
#range 查询price价格的区间
#相当于 select * from tb_hotel where price>=1100 and price<=1200
get /hotel/_search
{
"query":{
"range": {
"price": {
"gte": 1100,
"lte": 1200
}
}
}
}
#经纬度查询 查询指定举例的所有数据
#longitude、latitude 经度、纬度
#查询经纬度是31.21,121.5范围15KM的所有数据
#distance 以指定位置为中心的圆的半径。落入这个圆圈的点被认为是匹配的。距离可以用各种单位来表示
get /hotel/_search
{
"query":{
"geo_distance": {
"distance": "2km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
}
4.2:DSL对多个字段的查询
#---------------复合查询
#must 相当于sql的与 (city="上海" and price<=200)
#should 相当于sql的或
#must_not 相当于不等于 不参与算分
#filter 也是必须匹配 不参与算分
#select * from tb_hotel where city="上海" and price<=210
get /hotel/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"city": {
"value": "上海"
}
}
},
{
"range": {
"price": {
"lte": 210
}
}
}
],
"should": [
{
"term": {
"brand": {
"value": "如家"
}
}
}
]
}
}
}
#select * from tb_hotel where name like "%如家%" and price<=400 查询到27条数据
#并且距离指定位置 10km以内 只有三家
#_score分数不一致
get /hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "如家"
}
}
],
"must_not": [
{
"range": {
"price": {
"gt": 400
}
}
}
],
"filter": [
{
"geo_distance": {
"distance": "10km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
]
}
}
}
#select * from tb_hotel where name like "%如家%" and price<=400 查询到27条数据
#并且距离指定位置 10km以内 只有三家
#影响算分 _score分数不一致
get /hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "如家"
}
},
{
"geo_distance": {
"distance": "10km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
],
"must_not": [
{
"range": {
"price": {
"gt": 400
}
}
}
]
}
}
}
#---------------------------排序------
#select * from tb_hotel where name like "%如家%" and price<=400 查询到27条数据
#并且距离指定位置 10km以内 只有三家
#_score分数不一致
get /hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "如家"
}
},
{
"geo_distance": {
"distance": "10km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
],
"must_not": [
{
"range": {
"price": {
"gt": 400
}
}
}
]
}
},
"sort": [
{
"price":"asc"
},
{
"score":"desc"
}
]
}
#对location的位置进行排序 举例坐标点距离位置开始排序
get /hotel/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 31.034661,
"lon": 121.612282
},
"order":"asc",
"unit":"km"
}
}
]
}
#分页 select * from table limit start,size;
#from 相当于limit的start 起始位置 默认值是0
#size 相当于limit的size 查询数据长度
#from+size<=10000 因为分页是结果分页 查询全部 在分页
get /hotel/_search
{
"query": {
"match_all": {}
},
"from":99,
"size":10,
"sort": [
{
"_geo_distance": {
"location": {
"lat": 31.034661,
"lon": 121.612282
},
"order":"asc",
"unit":"km"
}
}
]
}
#高亮实现
#highlight 设置高亮字段
#<em>如家</em>酒店(北京良乡西路店)
#name字段的返回值有了<em>标签 前端只需要设置css就行了
get /hotel/_search
{
"query": {
"match": {
"all": "如家"
}
},
"highlight": {
"fields": {
"name":{
"require_field_match": "false"
}
}
}
}
#高亮实现
get /hotel/_search
{
"query": {
"match": {
"name": "如家"
}
},
"highlight": {
"boundary_scanner_locale":"zh_CN",
"fields": {
"name": {
"pre_tags": [
"<em>"
],
"post_tags": [
"</em>"
]
}
}
}
}
5:java代码复杂查询
5.1:Java代码简单查询
相当于sql的根据ID的增删改查,批量添加数据库
@SpringBootTest
class 文档操作_简单查询Demo {
@Autowired
TbHotelServiceImpl tbHotelService;
@Autowired
ElasticsearchClient elasticsearchClient;
//添加数据 IndexRequest
@Test
void addDocument() throws IOException {
//数据库查询到一条数据
TbHotel hotel = tbHotelService.getById(36934L);
TbHotelDoc hotelDoc=new TbHotelDoc(hotel);
System.out.println(hotelDoc);
//数据插入ES
IndexRequest indexRequest=new IndexRequest.Builder<TbHotelDoc>()
.id("11")
.index("hotel")
.document(hotelDoc).build();
elasticsearchClient.index(indexRequest);
}
//批量添加数据 BulkRequest
@Test
void addAllDocument() throws IOException {
//查询所有数据
List<TbHotel> list = tbHotelService.list();
System.out.println("list:"+list.size());
//将数据添加到ES中
BulkRequest.Builder builder = new BulkRequest.Builder();
for (TbHotel hotel : list) {
TbHotelDoc hotelDoc=new TbHotelDoc(hotel);
builder.operations(op->op.index(
idx->idx.index("hotel")
.id(hotelDoc.getId().toString())
.document(hotelDoc)
));
}
elasticsearchClient.bulk(builder.refresh(Refresh.WaitFor).build());
}
//根据id查询数据 GetRequest
@Test
void selectByIDDocument() throws IOException {
//GetRequest查询 查询单个
System.out.println("========查询单个GetRequest=======");
GetRequest getRequest = new GetRequest.Builder().index("hotel").id("36934").build();
GetResponse<TbHotelDoc> tbHotelDocGetResponse = elasticsearchClient.get(getRequest, TbHotelDoc.class);
boolean found = tbHotelDocGetResponse.found();
if (found) {
TbHotelDoc hotelDoc = tbHotelDocGetResponse.source();
System.out.println("查询数据是:"+hotelDoc);
} else {
System.out.println("没有查询到");
}
}
//查询全部数据 SearchRequest
//默认查询10条
@Test
void selectAlLDocument() throws IOException {
//查询全部SearchRequest
System.out.println("========查询全部SearchRequest=======");
SearchRequest searchRequest = new SearchRequest.Builder().index("hotel").build();
SearchResponse<TbHotelDoc> search = elasticsearchClient.search(searchRequest, TbHotelDoc.class);
List<Hit<TbHotelDoc>> hits = search.hits().hits();
for (Hit<TbHotelDoc> hit : hits) {
TbHotelDoc hotel = hit.source();
System.out.println(hotel);
}
}
//根据id修改数据 UpdateRequest
@Test
void updateDocument() throws IOException {
TbHotelDoc tbHotelDoc=new TbHotelDoc();
//需要更新哪个字段就赋值哪个字段
tbHotelDoc.setAddress("上海xx");
//修改这条数据
UpdateRequest<TbHotelDoc, TbHotelDoc> updateRequest = new UpdateRequest.Builder<TbHotelDoc, TbHotelDoc>()
.index("hotel")
.id("36934")
.doc(tbHotelDoc)
.build();
UpdateResponse<TbHotelDoc> update = elasticsearchClient.update(updateRequest, TbHotelDoc.class);
System.out.println(update);
//直接使用接口编程修改
TbHotelDoc hotelDoc=new TbHotelDoc();
//需要更新哪个字段就赋值哪个字段
hotelDoc.setCity("xx");
elasticsearchClient.update(updateRequest1->updateRequest1
.index("hotel")
.id("36934")
.doc(hotelDoc)
,TbHotelDoc.class);
}
//根据id删除数据 deleteRequest
@Test
void deleteDocument() throws IOException {
DeleteResponse hotel = elasticsearchClient.delete(deleteRequest -> deleteRequest
.index("hotel")
.id("12"));
System.out.println(hotel);
//删除全部
// elasticsearchClient.delete(deleteRequest->deleteRequest
// .index("hotel").id("11"));
}
}
5.2:Java代码复杂查询
相当于的sql的where 后边跟随多个条件
@SpringBootTest
class 文档操作_复杂查询Demo {
@Autowired
TbHotelServiceImpl tbHotelService;
@Autowired
ElasticsearchClient elasticsearchClient;
//查询全部数据 默认分页 查询10条数据
// select * from tb_hotel limit 0,10
@Test
void selectAll() throws IOException {
SearchRequest searchRequest = new SearchRequest.Builder()
.index("hotel")
.build();
SearchResponse<TbHotelDoc> search = elasticsearchClient.search(searchRequest, TbHotelDoc.class);
long value = search.hits().total().value();
System.out.println(value);
List<Hit<TbHotelDoc>> hits = search.hits().hits();
for (int i = 0; i < hits.size(); i++) {
System.out.println("数据是" + i + ":" + hits.get(i).source());
}
System.out.println("=====分割线======");
SearchResponse<TbHotelDoc> search1 = elasticsearchClient.search(s ->
s.index("hotel")
.query(q ->
q.matchAll(QueryBuilders.matchAll().build()))
, TbHotelDoc.class
);
List<Hit<TbHotelDoc>> hits1 = search1.hits().hits();
for (int i = 0; i < hits1.size(); i++) {
System.out.println("数据是" + i + ":" + hits1.get(i).source());
}
}
//查询全部数据
//match 查询字段必须是text 只能有一个条件
@Test
void matchTest() throws IOException {
System.out.println("=====match测试======");
SearchResponse<TbHotelDoc> search1 = elasticsearchClient.search(s ->
s.index("hotel")
.query(q ->
q.match(t -> t.query("如家").field("all")))
, TbHotelDoc.class
);
long value = search1.hits().total().value();
System.out.println("查询行数:" + value);
List<Hit<TbHotelDoc>> hits1 = search1.hits().hits();
for (int i = 0; i < hits1.size(); i++) {
System.out.println("数据是" + i + ":" + hits1.get(i).source());
}
}
//精准匹配
//#--------精确 针对type=keyword、id、数值、布尔类型 这些字段必须精确匹配------
// #term 精确匹配
//# city "type": "keyword" 的精确查询
//select * from tb_hotel where city="上海"
//select * from tb_hotel where score=35
//select * from tb_hotel where starName="四星级"
@Test
void term1Test() throws IOException {
System.out.println("=====term测试======");
SearchResponse<TbHotelDoc> search1 = elasticsearchClient.search(
s -> s.index("hotel")
.query(q ->
//q.term(t->t.field("city").value("上海"))
//q.term(t->t.field("score").value(35))
q.term(t -> t.field("starName").value("四星级"))
)
, TbHotelDoc.class
);
long value = search1.hits().total().value();
System.out.println("查询行数:" + value);
List<Hit<TbHotelDoc>> hits1 = search1.hits().hits();
for (int i = 0; i < hits1.size(); i++) {
System.out.println("数据是" + i + ":" + hits1.get(i).source());
}
}
/**
* #---------------复合查询
* #must 相当于sql的与 (city="上海" and price<=200)
* #should 相当于sql的或
* #must_not 相当于不等于 不参与算分
* #filter 也是必须匹配 不参与算分
* select * from tb_hotel where city="上海" and price<=200 and price>=100 and brand="如家" limit 0,5 order by price desc
*/
@Test
void boolTest() throws IOException {
System.out.println("=====复合查询测试======");
// BoolQuery boolQuery = QueryBuilders.bool().build();
Query city = MatchQuery.of(o -> o.field("city").query("上海"))._toQuery();
Query price = RangeQuery.of(o -> o.field("price").gt(JsonData.of(100)).lt(JsonData.of(200)))._toQuery();
Query filter = MatchQuery.of(o -> o.field("brand").query("如家"))._toQuery();
Query filter1 = MatchQuery.of(o -> o.field("starName").query("二钻"))._toQuery();
//
// boolQuery.must().add(city);
// boolQuery.must().add(price);
// boolQuery.filter().add(filter);
SearchResponse<TbHotelDoc> search1 = elasticsearchClient.search(
s -> s.index("hotel")
.query(q -> q.bool(builder -> builder
.must(city)
.must(price)
.filter(filter)
.filter(filter1)
)
)
.sort(ss -> ss.field(f -> f.field("price").order(SortOrder.Desc)))
.from(0)//数据起始位置 用于分页
.size(5)//数据长度 用于分页
.highlight(h -> h.fields("name", f -> f
.preTags("<em>")
.postTags("</em>")
).requireFieldMatch(false)
)
, TbHotelDoc.class
);
long value = search1.hits().total().value();
System.out.println("查询行数:" + value);
List<Hit<TbHotelDoc>> hits1 = search1.hits().hits();
for (int i = 0; i < hits1.size(); i++) {
TbHotelDoc source = hits1.get(i).source();
String name = hits1.get(i).highlight().get("name").get(0);
source.setName(name);
System.out.println("数据是" + i + ":" + source);
}
}
}
复杂查询2案例:
模拟实际的应用程序,前端点击品牌、价格、城市、星级、地理坐标等按钮选择酒店,这里就是ES的代码实现方式
@Autowired
ElasticsearchClient elasticsearchClient;
/**
* 前端controller接受json 转换成参数实体
* {
* "key":"",
* "page":1,
* "size":10,
* "sortBy":"price",
* "city":"上海",
* "brand":"万豪",
* "starName": "",
* "minPrice": 0,
* "maxPrice":1000,
* "locaction":"31.119187,121.618966"
* }
*
* RequestParams属性如下
* String key;//搜索关键字
* Integer page;//当前页
* Integer size;//当前页 数据长度
* String sortBy;//排序字段
* String city;//城市
* String brand;//品牌
* String starName;//星级
* Integer minPrice;//最小价格
* Integer maxPrice;//最大价格
* String location;//位置坐标
*
* <p>
* ES查询数据
* select * from tb_hotel where city="上海" and price<=200 and price>=100 and brand="如家"
*/
@Override
public PageResult getAllHotel(RequestParams requestParams) {
//构建BoolQuery
BoolQuery.Builder boolQuery = QueryBuilders.bool();
//判断关键字是否为空
String key = requestParams.getKey();//key是关键字
Query keys;
if (key == null || ("").equals(key)) {
keys = QueryBuilders.matchAll().build()._toQuery();
boolQuery.must(keys);
} else {
keys = MatchQuery.of(o -> o.field("all").query(key))._toQuery();
boolQuery.must(keys);
}
//1:判断city是否为空
String city = requestParams.getCity();
Query filter_city = null;
if (city != null && !city.equals("")) {
filter_city = MatchQuery.of(o -> o.field("city").query(city))._toQuery();
boolQuery.filter(filter_city);
}
//2:判断brand 品牌 是否为空
String brand = requestParams.getBrand();
Query filter_brand = null;
if (brand != null && !brand.equals("")) {
filter_brand = MatchQuery.of(o -> o.field("brand").query(brand))._toQuery();
boolQuery.filter(filter_brand);
}
//3:判断starName 星级 是否为空
String starName = requestParams.getStarName();
Query filter_starName = null;
if (starName != null && !starName.equals("")) {
filter_starName = MatchQuery.of(o -> o.field("starName").query(starName))._toQuery();
boolQuery.filter(filter_starName);
}
//4:判断Price 价格 是否为空
Integer minPrice = requestParams.getMinPrice();
Integer maxPrice = requestParams.getMaxPrice();
Query filter_Price;
if (minPrice != null && !maxPrice.equals("")) {
filter_Price = RangeQuery.of(o -> o.field("price").gt(JsonData.of(minPrice)).lt(JsonData.of(maxPrice)))._toQuery();
boolQuery.filter(filter_Price);
}
//5:判断locaction 坐标 是否为空 按照距离排序
// "lat":31.034661,
// "lon":121.612282
String location = requestParams.getLocaction();
GeoLocation of = null;
if (location != null && !location.equals("")) {
String[] split = location.split(",");
//这是地理坐标
of = GeoLocation.of(g -> g.latlon(l -> l.lat(Double.parseDouble(split[0])).lon(Double.parseDouble(split[1]))));
}
BoolQuery build = boolQuery.build();
//分页参数
Integer page = requestParams.getPage();
Integer size = requestParams.getSize();
//ES查询数据
SearchResponse<TbHotelDoc> search1 = null;
try {
GeoLocation finalOf = of;
search1 = elasticsearchClient.search(
s -> s.index("hotel")
.query(builder -> builder.bool(build)
)
//.sort(ss -> ss.field(f -> f.field("price").order(SortOrder.Desc)))
.sort(ss -> ss.geoDistance(g -> g
.field("location")
.location(finalOf)
.order(SortOrder.Asc)
.unit(DistanceUnit.Kilometers)))
.from((page - 1) * size)//数据起始位置 用于分页
.size(size)//数据长度 用于分页
, TbHotelDoc.class
);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
//封装返回值数据
long total = search1.hits().total().value();
List<TbHotelDoc> list = new ArrayList<>();
List<Hit<TbHotelDoc>> hits1 = search1.hits().hits();
for (int i = 0; i < hits1.size(); i++) {
//获取查询距离 b的值就是查询数据 到指定地点的的距离
List<FieldValue> sort = hits1.get(i).sort();
double b = sort.get(0).doubleValue();
//获取查询酒店结果 用自定义的TbHotelDoc封装
TbHotelDoc source = hits1.get(i).source();
//将距离数据set进去
source.setJuli(b);
list.add(source);
System.out.println("数据是" + i + ":" + source);
}
//返回结果PageResult 两个参数
//Long total; es的数据总行数
//List<TbHotelDoc> tbHotelDocs; 返回结果集
PageResult pageResult = new PageResult();
pageResult.setTotal(total);
pageResult.setTbHotelDocs(list);
return pageResult;
}