ElasticSearch第二章(ES8.X的使用)

这篇具有很好参考价值的文章主要介绍了ElasticSearch第二章(ES8.X的使用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1:ES的使用(DSL创建索引库-相当于表)

1.1:什么是索引库

1.2:索引库的增删改查使用

2:ES的使用(DSL操作文档-相当于数据)

2.1:什么是文档

2.2:文档的增删改查

3:java代码开发

3.1:准备工作

3.2:代码操作索引(也就是表的增删改查)

3.3:代码操作文档(也就是数据的增删改查)

4:DSL实现复杂的查询

4.1:DSL对单个字段的查询

4.2:DSL对多个字段的查询

5:java代码复杂查询

5.1:Java代码简单查询

5.2:Java代码复杂查询


1:ES的使用(DSL创建索引库-相当于表)

这些都是在kibana的开发者工具中测试的curl的DSL语句,因为ES是RESTFul风格的,这里使用kibana工具测试

es8 是否有copy_to,框架_ElasticSearch,elasticsearch,数据库,大数据

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的代码实现方式文章来源地址https://www.toymoban.com/news/detail-842629.html

  @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;
    }

到了这里,关于ElasticSearch第二章(ES8.X的使用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • es8 text类型使用term精确查询失效

    问题: 在使用term精确查询text 类型时,比如phone 手机号数值时可以查询到,使用nickname 这种text 查询不到。 我的mapping 是这样的     解决: 1. 通过es提供的测试分词的接口,我们可以测试各字段的分词情况 分别分词为’北‘,京,大,学,并没有我想要的整体的一块的分词

    2023年04月11日
    浏览(42)
  • 第二章前端开发ES6基础

    目录 扩展运算符 概述 语法 应用 模板字符串 概述 应用 内置对象扩展 概述 数组扩展方法 字符串扩展方法 set数据结构 概述 基本使用 操作方法 遍历方法 认识symbol 概述 作用 基本使用 项目 扩展运算符 概述 扩展运算符(spread operator)是 ES6 中新增的一种运算符,用 三个点(

    2024年02月07日
    浏览(49)
  • java与es8实战之四:SpringBoot应用中操作es8(无安全检查)

    这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇是《java与es8实战》系列的第四篇,系列文章写到现在,连个HelloWorld都没运行起来,实在说不过去了... 因此,本篇总体目标明确:实战在SpringBoot应用中操作elasticsearch8 为了降低难度,本篇部署的

    2024年02月11日
    浏览(40)
  • Java与es8实战之二:Springboot集成es8的Java Client

    配置springboot的application.yml 配置es的自签证书 执行如下命令将es容器中的crt文件复制到本地 docker cp 容器名称:/usr/share/elasticsearch/config/certs/http_ca.crt . 将crt文件放至springboot项目的resource路径下

    2024年02月12日
    浏览(42)
  • 【Elasticsearch】从零开始搭建ES8集群并且集成到Springboot,更好的服务电商类等需要全文索引的项目(一)

    最近公司的电商项目越来越庞大,功能需求点也越来越多,各种C端对查询和检索的要求也越来越高,是时候在项目中引入全文检索了。 ElasticSearch 是一个基于 Lucene 的搜索服务器,它提供了一个分布式多用户能力的全文搜索引擎,并且是基于Java 开发的,我记得很久之前ES还不

    2024年02月15日
    浏览(48)
  • ES8 集群部署

    准备至少三个节点,配置至少为4核心8G内存 节点名称 节点IP node1 192.168.0.1 node2 192.168.0.2 node3 192.168.0.3 关闭三个节点的防火墙 ​ 1、添加ES用户 es不允许root启动 2、创建安装目录并授权 3、修改操作系统配置 ​ 注意:请严格按照安装顺序来,否则都是坑 ​ 以下步骤都在用户

    2024年02月01日
    浏览(63)
  • es8.8 集群安装笔记

    本次安装使用centos8 3节点安装: 192.168.182.142 192.168.182.143 192.168.182.144 官网 可以查看详细的安装,安装步骤比较简单 https://www.elastic.co/guide/en/elasticsearch/reference/8.8/rpm.html#rpm-repo 访问需要用https https://127.0.0.1:9200/ 默认用户 elastic 密码就是安装的时候打印到屏幕上的密码 8.8 使用

    2024年02月13日
    浏览(44)
  • ES8生产实践——pod日志采集(Fluentd方案)

    Fluentd是一个是一个开源的日志收集和传输工具,旨在解决日志数据的收集、传输和处理问题,它可以收集来自于各种系统或应用的日志,转化为用户指定的格式后,转发到用户所指定的日志存储系统之中。 用图来说明问题的话,在没有使用之前Fluentd,日志采集过滤存储流程

    2024年02月09日
    浏览(42)
  • 【好书推荐】JavaScript Es8 函数式编程实践入门

    Anto Aravinth从事软件行业已经6年多了。他开发了许多用新技术编写的系统。Anto了解JavaScript的基础知识及其工作方式,并培训了许多人。Anto在业余时间也做OSS,他喜欢打乒乓球。 Srikanth Machiraju作为开发人员、架构师、技术培训师和社区发言人,拥有超过10年的工作经验。他目

    2024年02月08日
    浏览(40)
  • 最新安装es8.12.2、es-ik分词器、kibana-8.12.2

    目录 下载官网安装包 百度网盘 提取码:koko Elasticsearch官网 es-ik分词器下载地址 kibana下载地址 es安装部署 上传安装包 解压 添加用户组添加用户 更改目录 Owner 更换es用户 修改 config 包下配置文件 elasticsearch.yml 如下: 修改启动内存大小 启动es 测试验证 本地访问不了原因: 1、

    2024年03月18日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包