【Solr】之使用springboot完成对【京东搜索商品】案例的实现

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 【Solr】之使用springboot完成对【京东搜索商品】案例的实现

一、案例逻辑


20200715103242401.png


1.1 solr搜索实现三步走实现


1,需要把商品的数据导入到Solr 里面

2,根据条件编写各种代码实现搜索

3,使用定时任务定时同步数据库和solr的数据【当然应该提供手动同步】



1.2 solr搜索说明


1.2.1 关键字搜索 copyField[数组]去完成

20200715103437544.png


1.2.2 分页


20200715103506277.png


1.2.3 过滤条件

20200715103529456.png


1.2.4 排序


20200715103558761.png


1.2.5 高亮

20200715103628447.png

1.2.6 价格区间


20200715104035990.png


二、准备数据库


jd-shop

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for goods
-- ----------------------------
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods`  (
  `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '商品ID',
  `name` varchar(300) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '商品名称',
  `shopid` bigint(20) NULL DEFAULT NULL COMMENT '店铺id',
  `oriprice` decimal(15, 2) NULL DEFAULT 0.00 COMMENT '原价',
  `price` decimal(15, 2) NULL DEFAULT NULL COMMENT '现价',
  `remark` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '' COMMENT '简要描述,卖点等',
  `content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '详细描述',
  `picture` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品主图',
  `imgs` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '商品图片,以,分割',
  `status` int(1) NULL DEFAULT 0 COMMENT '默认是1,表示正常状态, -1表示删除, 0下架',
  `categoryid` bigint(20) UNSIGNED NULL DEFAULT NULL COMMENT '商品分类',
  `salenum` int(11) NULL DEFAULT NULL COMMENT '销量',
  `totalstocks` int(11) NULL DEFAULT 0 COMMENT '总库存',
  `deliverymode` json NULL COMMENT '配送方式json',
  `deliverytemplateid` bigint(20) NULL DEFAULT NULL COMMENT '运费模板id',
  `createtime` datetime(0) NULL DEFAULT NULL COMMENT '录入时间',
  `updatetime` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  `filters` json NULL COMMENT '{\"is_jd_express\":true,\"is_second-hand\":true,\"is_new\":true,\"is_to_pay\":true} 是否京东快递,是否二手,是否新品,是否支持货到付款',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `shop_id`(`shopid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 95 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '商品' ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES (1, 'Apple iPhone XS Max 移动联通电信4G手机 111111', 1, 0.00, 1.01, '6.5英寸大屏,支持双卡。', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 93, 0, 95, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 78, '2019-03-29 14:40:00', '2020-04-04 15:07:24', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (2, '兰蔻粉水清滢柔肤水400ml 爽肤水女保湿舒缓滋润嫩肤', 1, 0.00, 420.00, '好看耐穿', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 87, 0, 0, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 48, '2019-04-21 19:15:34', '2020-04-04 15:07:34', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (3, '【Dole都乐】菲律宾都乐非转基因木瓜1只 单只约410g', 1, 0.00, 26.00, '包邮 肉厚籽少 独具风味', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 95, 0, 0, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-04-21 21:56:38', '2020-04-04 15:07:34', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (4, '阿迪达斯官方 adidas 三叶草 NITE JOGGER 男子经典鞋BD7956', 1, 10.00, 1199.00, ' 运动鞋/休闲鞋', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 0, 88, 0, 0, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-04-21 22:10:04', '2020-04-04 15:07:35', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (5, '【Dole都乐】比利时Truval啤梨12只 进口水果新鲜梨 单果120g左右', 1, 0.00, 38.00, '好吃', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 95, 100, 15, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-04-22 16:43:33', '2020-04-04 15:07:36', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (6, '旗舰店官网 自拍神器 梵高定制', 1, 10.00, 6998.00, '梵高定制礼盒 全球限量发售 分期免息', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 85, 0, 99, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-04-23 15:43:26', '2020-04-04 15:07:36', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (7, '餐厅装饰画现代简约饭厅挂画墙面壁画好好吃饭', 1, 169.00, 169.00, '创意餐厅装饰画 好好吃饭', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 91, 0, 0, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-04-25 10:22:21', '2020-04-04 15:07:37', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (8, '阴阳师寮办秘制 月见和菓子 184克', 1, 0.00, 22.00, '三层夹心,Q弹有料', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 95, 0, 77, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-04-27 11:37:13', '2020-04-04 15:07:37', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (9, '旺仔牛奶', 2, 0.00, 100.00, '测试', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 95, 0, 0, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 48, '2019-05-22 10:39:49', '2020-04-04 15:07:38', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (10, '测试商品A', 1, 30.00, 30.00, '牛逼', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 95, 0, 30, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-05-23 17:23:11', '2020-04-04 15:07:38', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (11, '测试商品B', 1, 40.00, 40.00, 'BBBB', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 95, 0, 40, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-05-23 17:24:06', '2020-04-04 15:07:39', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (12, '测试商品C', 1, 60.00, 50.00, 'CCC', '<p>测试商品</p>', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 'https://img12.360buyimg.com/n7/jfs/t7297/154/3413903491/65679/45ae4902/59e42830N9da56c41.jpg', 1, 95, 0, 50, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 47, '2019-05-23 17:24:48', '2020-04-04 15:07:39', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (13, '华为鲸鱼手机', 1, 0.00, 0.00, '5G快速四摄高清', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/00/rBPi511H47aAEkS9AAD0Hf0JFCw449.jpg', 'http://47.101.176.118/g1/M00/00/00/rBPi511H47aAEkS9AAD0Hf0JFCw449.jpg', 1, 93, 0, 0, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 59, '2019-08-05 17:13:41', '2020-04-04 15:07:40', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (14, '鲸鱼', 1, 0.00, 0.00, '鲸鱼好吃的鲸鱼', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/00/rBPi511H8_KAWI_tAAAH1Pr_MrM101.jpg', 'http://47.101.176.118/g1/M00/00/00/rBPi511H8_KAWI_tAAAH1Pr_MrM101.jpg', 1, 96, 0, 0, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 59, '2019-08-05 17:17:31', '2020-04-04 15:07:40', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (15, '华为Mate 20 PRO', 1, 0.00, 1.00, '5G四摄索引麒麟980', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/00/rBPi511H9P6AW6-sAAD0Hf0JFCw913.jpg', 'http://47.101.176.118/g1/M00/00/00/rBPi511H9P6AW6-sAAD0Hf0JFCw913.jpg', 1, 93, 0, 4, '{\"hasUserPickUp\": false, \"hasShopDelivery\": true}', 59, '2019-08-05 17:24:15', '2020-04-04 15:07:41', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (16, '算法导论第四版', 1, 0.00, 11.00, '你学不会', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/00/rBPi511Tdt2Aa6pQAABcteVfoYk808.jpg', 'http://47.101.176.118/g1/M00/00/00/rBPi511Tdt2Aa6pQAABcteVfoYk808.jpg', 1, 94, 0, 11, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 47, '2019-08-14 10:58:09', '2020-04-04 15:07:41', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (17, '算法导论第四版', 1, 0.00, 11.00, '你学不会', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/00/rBPi511Tdt2Aa6pQAABcteVfoYk808.jpg', 'http://47.101.176.118/g1/M00/00/00/rBPi511Tdt2Aa6pQAABcteVfoYk808.jpg', 1, 94, 0, 11, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 47, '2019-08-14 10:58:10', '2020-04-04 15:07:42', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (18, '算法导论第N版', 1, 0.00, 1.00, '学不会', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/01/rBPi511TeU6AUZ1hAABcteVfoYk222.jpg', 'http://47.101.176.118/g1/M00/00/01/rBPi511TeU6AUZ1hAABcteVfoYk222.jpg', 1, 94, 0, 1, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 47, '2019-08-14 11:01:19', '2020-04-04 15:07:42', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (19, '锤子(smartisan) 坚果Pro3 8GB+128GB 黑色 骁龙855PLUS 4800万四摄 全网通双卡双待 全面屏游戏手机', 1, 2289.00, 2289.00, '稀缺货源,限量抢购】2K+90Hz流体屏,骁龙855旗舰,4800万超广角三摄,影音娱乐不在话下', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/01/rBPi511Ted6AV01_AABcteVfoYk963.jpg', 'http://47.101.176.118/g1/M00/00/01/rBPi511Ted6AV01_AABcteVfoYk963.jpg', 1, 93, 0, 0, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 47, '2019-08-14 11:03:23', '2020-04-04 15:07:43', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (20, '荣耀9X 麒麟810 4000mAh续航 4800万超清夜拍 6.59英寸升降全面屏 全网通6GB+64GB 魅海蓝', 1, 1289.00, 1289.00, '稀缺货源,限量抢购】2K+90Hz流体屏,骁龙855旗舰,4800万超广角三摄,影音娱乐不在话下', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/01/rBPi511Ted6AV01_AABcteVfoYk963.jpg', 'http://47.101.176.118/g1/M00/00/01/rBPi511Ted6AV01_AABcteVfoYk963.jpg', 1, 93, 0, 0, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 47, '2019-08-14 11:03:23', '2020-04-04 15:07:43', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (21, 'Apple iPhone 11 (A2223) 128GB 黑色 移动联通电信4G手机 双卡双待', 1, 5999.00, 5999.00, '稀缺货源,限量抢购】2K+90Hz流体屏,骁龙855旗舰,4800万超广角三摄,影音娱乐不在话下', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/01/rBPi511Ted6AV01_AABcteVfoYk963.jpg', 'http://47.101.176.118/g1/M00/00/01/rBPi511Ted6AV01_AABcteVfoYk963.jpg', 1, 93, 0, 0, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 47, '2019-08-14 11:03:25', '2020-04-04 15:07:43', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (22, '一加 OnePlus 7T 90Hz流体屏 骁龙855Plus旗舰 4800万超广角三摄 8GB+256GB 冰川银 全面屏拍照游戏手机', 1, 3199.00, 3199.00, '稀缺货源,限量抢购】2K+90Hz流体屏,骁龙855旗舰,4800万超广角三摄,影音娱乐不在话下', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/01/rBPi511Ted6AV01_AABcteVfoYk963.jpg', 'http://47.101.176.118/g1/M00/00/01/rBPi511Ted6AV01_AABcteVfoYk963.jpg', 1, 93, 0, 0, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 47, '2019-08-14 11:05:43', '2020-04-04 15:07:45', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
INSERT INTO `goods` VALUES (23, '努比亚 nubia X 双面屏 深空灰 8GB+128GB 全网通 移动联通电信4G手机 双卡双待', 1, 2399.00, 2399.00, '【火爆销售中】双屏黑科技,骁龙845,AOD熄屏,双摄AI美颜自拍', '<p>测试商品</p>', 'http://47.101.176.118/g1/M00/00/01/rBPi511TeqGAdjQfAABcteVfoYk439.jpg', 'http://47.101.176.118/g1/M00/00/01/rBPi511TeqGAdjQfAABcteVfoYk439.jpg', 1, 85, 0, 1, '{\"hasUserPickUp\": true, \"hasShopDelivery\": false}', 47, '2019-08-14 11:07:04', '2020-04-04 15:07:44', '{\"is_new\": true, \"is_to_pay\": true, \"is_jd_express\": true, \"is_second_hand\": true}');
SET FOREIGN_KEY_CHECKS = 1;


updatetime 是最后做增加更新时使用


三、创建项目


3.1 springboot项目202007151101398.png

20200715110206643.png

3.2修改pom.xml添加Druid和mybatisplus的依赖


<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.1.tmp</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.21</version>
</dependency>


3.3 配置yml

#端口
server:
  port: 8080
spring:
  #数据源的配置
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/jd-shop?serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  application:
    name: jd-search
  data:
    solr:
      host: http://47.95.34.202:8983/solr/jd-shop
#配置mybatisplus
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:mapper/*.xml
  global-config:
    db-config:
      id-type: auto

3.4 使用插件生成Goods和GoodsMapper


3.4.1 准备工作

20200715111107656.png


3.4.2 安装插件


20200715111615648.png

https://zhile.io/2019/04/23/mybatis-code-helper-pro-crack.html

20200715111651374.png

OK之后重启IDEA


3.4.3 生成Goods,GoodsMapper,XML


Goods

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "goods")
public class Goods {
    /**
     * 商品ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 商品名称
     */
    @TableField(value = "name")
    private String name;
    /**
     * 店铺id
     */
    @TableField(value = "shopid")
    private Long shopid;
    /**
     * 原价
     */
    @TableField(value = "oriprice")
    private BigDecimal oriprice;
    /**
     * 现价
     */
    @TableField(value = "price")
    private BigDecimal price;
    /**
     * 简要描述,卖点等
     */
    @TableField(value = "remark")
    private String remark;
    /**
     * 详细描述
     */
    @TableField(value = "content")
    private String content;
    /**
     * 商品主图
     */
    @TableField(value = "picture")
    private String picture;
    /**
     * 商品图片,以,分割
     */
    @TableField(value = "imgs")
    private String imgs;
    /**
     * 默认是1,表示正常状态, -1表示删除, 0下架
     */
    @TableField(value = "status")
    private Integer status;
    /**
     * 商品分类
     */
    @TableField(value = "categoryid")
    private Long categoryid;
    /**
     * 销量
     */
    @TableField(value = "salenum")
    private Integer salenum;
    /**
     * 总库存
     */
    @TableField(value = "totalstocks")
    private Integer totalstocks;
    /**
     * 配送方式json
     */
    @TableField(value = "deliverymode")
    private Object deliverymode;
    /**
     * 运费模板id
     */
    @TableField(value = "deliverytemplateid")
    private Long deliverytemplateid;
    /**
     * 录入时间
     */
    @TableField(value = "createtime")
    private Date createtime;
    /**
     * 修改时间
     */
    @TableField(value = "updatetime")
    private Date updatetime;
    /**
     * {"is_jd_express":true,"is_second-hand":true,"is_new":true,"is_to_pay":true} 是否京东快递,是否二手,是否新品,是否支持货到付款
     */
    @TableField(value = "filters")
    private Object filters;
    public static final String COL_ID = "id";
    public static final String COL_NAME = "name";
    public static final String COL_SHOPID = "shopid";
    public static final String COL_ORIPRICE = "oriprice";
    public static final String COL_PRICE = "price";
    public static final String COL_REMARK = "remark";
    public static final String COL_CONTENT = "content";
    public static final String COL_PICTURE = "picture";
    public static final String COL_IMGS = "imgs";
    public static final String COL_STATUS = "status";
    public static final String COL_CATEGORYID = "categoryid";
    public static final String COL_SALENUM = "salenum";
    public static final String COL_TOTALSTOCKS = "totalstocks";
    public static final String COL_DELIVERYMODE = "deliverymode";
    public static final String COL_DELIVERYTEMPLATEID = "deliverytemplateid";
    public static final String COL_CREATETIME = "createtime";
    public static final String COL_UPDATETIME = "updatetime";
    public static final String COL_FILTERS = "filters";
}


GoodsMapper


public interface GoodsMapper extends BaseMapper<Goods> {
}


GoodsMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.solr.mapper.GoodsMapper">
    <resultMap id="BaseResultMap" type="com.example.solr.domain.Goods">
        <!--@mbg.generated-->
        <!--@Table goods-->
        <id column="id" jdbcType="BIGINT" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
        <result column="shopid" jdbcType="BIGINT" property="shopid" />
        <result column="oriprice" jdbcType="DECIMAL" property="oriprice" />
        <result column="price" jdbcType="DECIMAL" property="price" />
        <result column="remark" jdbcType="VARCHAR" property="remark" />
        <result column="content" jdbcType="LONGVARCHAR" property="content" />
        <result column="picture" jdbcType="VARCHAR" property="picture" />
        <result column="imgs" jdbcType="VARCHAR" property="imgs" />
        <result column="status" jdbcType="INTEGER" property="status" />
        <result column="categoryid" jdbcType="BIGINT" property="categoryid" />
        <result column="salenum" jdbcType="INTEGER" property="salenum" />
        <result column="totalstocks" jdbcType="INTEGER" property="totalstocks" />
        <result column="deliverymode" jdbcType="OTHER" property="deliverymode" />
        <result column="deliverytemplateid" jdbcType="BIGINT" property="deliverytemplateid" />
        <result column="createtime" jdbcType="TIMESTAMP" property="createtime" />
        <result column="updatetime" jdbcType="TIMESTAMP" property="updatetime" />
        <result column="filters" jdbcType="OTHER" property="filters" />
    </resultMap>
    <sql id="Base_Column_List">
        <!--@mbg.generated-->
        id, `name`, shopid, oriprice, price, remark, content, picture, imgs, `status`, categoryid,
        salenum, totalstocks, deliverymode, deliverytemplateid, createtime, updatetime, filters
    </sql>
</mapper>


3.4.4 修改主启动类

@SpringBootApplication
@MapperScan(basePackages = {"com.example.solr.mapper"})
public class SolrSpringbootJdApplication {
    public static void main(String[] args) {
        SpringApplication.run(SolrSpringbootJdApplication.class, args);
    }
}

3.4.5 测试mybatisplus和solr是否可用

20200715191050677.png

四、在solr里面创建jd-shop的core并配置好属性


4.1 创建jd-shop

20200715191156308.png

4.2 配置分词和属性[schema文件]

<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
  <field name="name" type="text_cn" indexed="true" stored="true" required="true" multiValued="false" />
  <field name="shopid" type="plong" indexed="true" stored="true" multiValued="false" />
  <field name="oriprice" type="pdouble" indexed="true" stored="true" multiValued="false" />
  <field name="price" type="pdouble" indexed="true" stored="true" multiValued="false" />
  <field name="remark" type="text_cn" indexed="true" stored="true" multiValued="false" />
  <field name="content" type="text_cn" indexed="true" stored="true" multiValued="false" />
  <field name="picture" type="string" indexed="false" stored="true" multiValued="false" />
  <field name="categoryid" type="plong" indexed="true" stored="true" multiValued="false" />
  <field name="salenum" type="pint" indexed="true" stored="true" multiValued="false" />
  <field name="totalstocks" type="pint" indexed="true" stored="true" multiValued="false" />
  <field name="is_jd_express" type="pint" indexed="true" stored="true" multiValued="false" />
  <field name="is_second-hand" type="pint" indexed="true" stored="true" multiValued="false" />
  <field name="is_new" type="pint" indexed="true" stored="true" multiValued="false" />
  <field name="is_to_pay" type="pint" indexed="true" stored="true" multiValued="false" />
  <field name="keywords" type="text_cn" indexed="true" stored="true" multiValued="true" />
  <copyField source="name" dest="keywords" />
  <copyField source="remark" dest="keywords" />
 <!--添加一个中文分词器IK-->
  <fieldType name="text_cn" class="solr.TextField" positionIncrementGap="100"> 
      <analyzer type="index">
       <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="true"/>
      </analyzer>
      <analyzer type="query">
       <tokenizer class="org.apache.lucene.analysis.ik.IKTokenizerFactory" useSmart="false"/>
      </analyzer>
    </fieldType>

覆盖到solr并重启


五、代码实现全量和增量导入


5.1 添加依赖并全量导入

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>

ImportService接口


public interface ImportService {
    /***
    * @Description:
    * @Param: 全量导入
    */
    public void importAll();
    /***
    * @Description:
    * @Param: 增量导入
    */
    public void importUpdate();
}


ImportServiceImpl

@Service
@Transactional
public class ImportServiceImpl implements ImportService {
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private SolrClient solrClient;
    @Override
    @PostConstruct  //只要IOC容器加载就运行
    public void importAll() {
        //查询出所有上架的商品
        QueryWrapper<Goods> qw=new QueryWrapper<>();
        qw.eq("status",1);
        List<Goods> goodsList = goodsMapper.selectList(qw);
        List<SolrInputDocument> docs=this.createDoc(goodsList);
        try {
            solrClient.add(docs);
            solrClient.commit();//提交
            System.out.println("数据全量同步成功:"+new Date());
        }catch (Exception e){
            System.out.println(e);
        }
    }
    /***
    * @Description: 构造文档集合
    * @Param: [goodsList]
    */
    private List<SolrInputDocument> createDoc(List<Goods> goodsList) {
        List<SolrInputDocument> docs=new ArrayList<>(goodsList.size());
        for (Goods g : goodsList) {
            SolrInputDocument doc=new SolrInputDocument();
            doc.addField("id",g.getId().toString());
            doc.addField("name",g.getName());
            doc.addField("shopid",g.getShopid().longValue());
            doc.addField("oriprice",g.getOriprice().doubleValue());
            doc.addField("price",g.getPrice().doubleValue());
            doc.addField("remark",g.getRemark());
            doc.addField("content",g.getContent());
            doc.addField("picture",g.getPicture());
            doc.addField("categoryid",g.getCategoryid().longValue());
            doc.addField("salenum",g.getSalenum().intValue());
            doc.addField("totalstocks",g.getTotalstocks().intValue());
            JSONObject jsonObject = JSON.parseObject(g.getFilters().toString());
            doc.addField("is_jd_express",jsonObject.get("is_jd_express").equals(true)?1:0);
            doc.addField("is_second_hand",jsonObject.get("is_second_hand").equals(true)?1:0);
            doc.addField("is_new",jsonObject.get("is_new").equals(true)?1:0);
            doc.addField("is_to_pay",jsonObject.get("is_to_pay").equals(true)?1:0);
            docs.add(doc);
        }
        return docs;
    }
    @Override
    public void importUpdate() {
    }
}


去控制台查看数据即可。


5.2 增量导入


修改ImportServiceImpl

@Service
@Log4j2
@Transactional
public class ImportServiceImpl implements ImportService {
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private SolrClient solrClient;
    @Override
    @PostConstruct  //只要IOC容器加载就运行
    public void importAll() {
        //查询出所有上架的商品
        QueryWrapper<Goods> qw=new QueryWrapper<>();
        qw.eq("status",1);
        List<Goods> goodsList = goodsMapper.selectList(qw);
        List<SolrInputDocument> docs=this.createDoc(goodsList);
        try {
            solrClient.add(docs);
            solrClient.commit();//提交
            log.info("数据全量同步成功:"+new Date());
        }catch (Exception e){
            System.out.println(e);
            log.warn("数据全量同步失败,{}",e);
        }
        this.lastSycnDate=new Date();
    }
    /***
    * @Description: 构造文档集合
    * @Param: [goodsList]
    */
    private List<SolrInputDocument> createDoc(List<Goods> goodsList) {
        List<SolrInputDocument> docs=new ArrayList<>(goodsList.size());
        for (Goods g : goodsList) {
            SolrInputDocument doc=new SolrInputDocument();
            doc.addField("id",g.getId().toString());
            doc.addField("name",g.getName());
            doc.addField("shopid",g.getShopid().longValue());
            doc.addField("oriprice",g.getOriprice().doubleValue());
            doc.addField("price",g.getPrice().doubleValue());
            doc.addField("remark",g.getRemark());
            doc.addField("content",g.getContent());
            doc.addField("picture",g.getPicture());
            doc.addField("categoryid",g.getCategoryid().longValue());
            doc.addField("salenum",g.getSalenum().intValue());
            doc.addField("totalstocks",g.getTotalstocks().intValue());
            JSONObject jsonObject = JSON.parseObject(g.getFilters().toString());
            doc.addField("is_jd_express",jsonObject.get("is_jd_express").equals(true)?1:0);
            doc.addField("is_second-hand",jsonObject.get("is_second-hand").equals(true)?1:0);
            doc.addField("is_new",jsonObject.get("is_new").equals(true)?1:0);
            doc.addField("is_to_pay",jsonObject.get("is_to_pay").equals(true)?1:0);
            docs.add(doc);
        }
        return docs;
    }
    //声明一个最后一次的导入时间
    private Date lastSycnDate=new Date();
    @Override
    @Scheduled(initialDelay = 5*1000,fixedRate = 5*1000)  //延时5秒执行 5秒循环一次
    public void importUpdate() {
        //查询出所有上架的商品
        QueryWrapper<Goods> qw=new QueryWrapper<>();
        qw.eq("status",1);
        qw.ge("updatetime",lastSycnDate);
        List<Goods> goodsList = goodsMapper.selectList(qw);
        List<SolrInputDocument> docs=this.createDoc(goodsList);
        try {
            solrClient.add(docs);
            solrClient.commit();//提交
            lastSycnDate=new Date();
            log.info("数据增量导入成功:"+lastSycnDate.toLocaleString());
        }catch (Exception e){
            System.out.println(e);
            log.warn("数据增量导入失败{}",e);
        }
    }
}

修改主启动类开启定时任务

@SpringBootApplication
@MapperScan(basePackages = {"com.example.solr.mapper"})
@EnableScheduling
public class SolrSpringbootJdApplication {
    public static void main(String[] args) {
        SpringApplication.run(SolrSpringbootJdApplication.class, args);
    }
}


六、编写代码实现搜索


6.1 创建DataGridView

@Data
@AllArgsConstructor
@NoArgsConstructor
public class DataGridView {
    private Integer code=0;
    private String msg="";
    private Long count;
    private Object data;
}

6.2 创建SearchService

public interface SearchService {
    /***
    * @Description:
    * @Param: [keywords, 关键字
     * page,  页码
     * limit,  每页显示条数
     * sort,  排序字段  1  价格 2 销量
     * priceScope,  价格区间  200-300
     * filters]  "is_jd_express":1,
     *         "is_second-hand":1,
     *         "is_new":1,
     *         "is_to_pay":1,
    * @return: DataGridView
    */
    DataGridView searchGoods(String keywords, Integer page, Integer limit, Integer sort, String priceScope, Map<String,Object> filters);
}

6.3 创建SearchServiceImpl

@Service
@Log4j2
public class SearchServiceImpl implements SearchService {
    @Autowired
    private SolrClient solrClient;
    /***
     * @Description:
     * @Param: [keywords, 关键字
     * page,  页码
     * limit,  每页显示条数
     * sort,  排序字段  1  价格升  2 价格降    3 销量升    4  销量降
     * priceScope,  价格区间  200-300
     * filters]  "is_jd_express":1,
     *         "is_second_hand":1,
     *         "is_new":1,
     *         "is_to_pay":1,
     * @return: DataGridView
     * @Author: 雷哥
     * @Date: 2020/4/4
     */
    @Override
    public DataGridView searchGoods(String keywords, Integer page, Integer limit,
                                    Integer sort, String priceScope, Map<String, Object> filters) {
        //关键字
        SolrQuery solrQuery=null;
        if(StringUtils.isEmpty(keywords)){
            solrQuery=new SolrQuery("*:*");
        }else{
            solrQuery=new SolrQuery("keywords:"+keywords);
        }
        //分页处理
        solrQuery.setStart((page-1)*limit);
        solrQuery.setRows(limit);
        //处理排序
        switch (sort){
            case 1://按价格升
                solrQuery.addSort("price",SolrQuery.ORDER.asc);
                break;
            case 2://按价格降
                solrQuery.addSort("price",SolrQuery.ORDER.desc);
                break;
            case 3://按销量升
                solrQuery.addSort("salenum",SolrQuery.ORDER.asc);
                break;
            case 4://按销量降
                solrQuery.addSort("salenum",SolrQuery.ORDER.desc);
                break;
        }
        //处理价格过滤
        List<String> filterList=new ArrayList<>();
        if(!StringUtils.isEmpty(priceScope)){
            String[] split = priceScope.split("-");
            if(split.length!=2){
                throw  new RuntimeException("传入的价格范围参数不合法");
            }
            filterList.add("price:["+split[0]+" TO "+split[1]+"]");
        }
        //处理其它过滤"is_jd_express":1,
        //     *         "is_second_hand":1,
        //     *         "is_new":1,
        //     *         "is_to_pay":1,
        if(!filters.isEmpty()){
            for (Map.Entry<String, Object> entry : filters.entrySet()) {
                filterList.add(entry.getKey()+":"+entry.getValue());
            }
        }
        //添加过滤条件
        if(!filterList.isEmpty()){
            solrQuery.addFilterQuery(filterList.toArray(new String[]{}));
        }
        //只要关键字不为空才设置高亮
       if(!StringUtils.isEmpty(keywords)){
           solrQuery.setHighlight(true);
           solrQuery.addHighlightField("name");
           solrQuery.addHighlightField("remark");
           solrQuery.setHighlightSimplePre("<font color=red>");
           solrQuery.setHighlightSimplePost("</font>");
       }
        DataGridView dataGridView=new DataGridView();
        List<Goods> goods=new ArrayList<>();
       try
       {
           QueryResponse query = solrClient.query(solrQuery);
           SolrDocumentList results = query.getResults();
           dataGridView.setCount(results.getNumFound());//设置总条数
           Map<String, Map<String, List<String>>> highlighting =null;
           if(solrQuery.getHighlight()){//如果开户高亮,就高亮查询
               highlighting=query.getHighlighting();
           }
           for (SolrDocument result : results) {
               Goods g=new Goods();
               g.setId(Long.valueOf(result.getFieldValue("id").toString()));
               g.setName(result.getFieldValue("name").toString());
               g.setShopid(Long.valueOf(result.getFieldValue("shopid").toString()));
               g.setOriprice(new BigDecimal(Double.valueOf(result.getFieldValue("oriprice").toString())));
               g.setPrice(new BigDecimal(Double.valueOf(result.getFieldValue("price").toString())));
               g.setRemark(result.getFieldValue("remark").toString());
               g.setContent(result.getFieldValue("content").toString());
               g.setPicture(result.getFieldValue("picture").toString());
               g.setCategoryid(Long.valueOf(result.getFieldValue("categoryid").toString()));
               g.setSalenum(Integer.valueOf(result.getFieldValue("salenum").toString()));
               g.setTotalstocks(Integer.valueOf(result.getFieldValue("totalstocks").toString()));
               //处理高亮
               if(solrQuery.getHighlight()){
                    if(null!=highlighting&&!highlighting.isEmpty()){
                        for (Map.Entry<String, Map<String, List<String>>> entry : highlighting.entrySet()) {
                            String key = entry.getKey();
                            Map<String, List<String>> value = entry.getValue();
                            if(value.containsKey("name")){
                                String hlName=value.get("name").get(0);
                                g.setName(hlName);
                            }
                            if(value.containsKey("remark")){
                                String hlRemark=value.get("remark").get(0);
                                g.setRemark(hlRemark);
                            }
                        }
                    }
               }
               goods.add(g);
           }
       }catch (Exception e){
           log.warn("查询失败{}",e);
       }
        dataGridView.setData(goods);
        return dataGridView;
    }
}


6.4 测试

@SpringBootTest
class SolrSpringbootJdApplicationTests {
    @Autowired
    private SearchService searchService;
    @Test
    void contextLoads() {
        Map<String, Object> filters=new HashMap<>();
        filters.put("is_jd_express",1);//要求京东快递
        DataGridView searchGoods = searchService.searchGoods("", 1, 5, 1, "70-500", filters);
        List<Goods> data = (List<Goods>) searchGoods.getData();
        for (Goods datum : data) {
            System.out.println(datum);
        }
    }
}

七、Solr控制台全量和增量导入配置


7.1 清空solr里面的数据

20200715192857431.png


7.2 导包


在solr安装目录下dist目录下有两个solr-dataimport**。.jar

引入mysql的驱动包


2020071520274461.png

20200715202752659.png


7.3 修改server/solr/jd-shop/conf/solrconfig.xml

<!--配置控制台的数据导入-->
     <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
        <lst name="defaults">
            <str name="config">data-config.xml</str>
        </lst>
    </requestHandler>


7.4 创建server/solr/jd-shop/conf/data-conf.xml的文件

<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig> 
    <!--配置数据源-->
    <dataSource type="JdbcDataSource"
                driver="com.mysql.jdbc.Driver"
                url="jdbc:mysql://127.0.0.1:3306/jd-shop?serverTimezone=UTC"
                user="root"
                password="123456"/>
    <document> 
        <entity name="goods" 
          query="select id,name,shopid,oriprice,price,remark,content,picture,categoryid,salenum,totalstocks,
                case  JSON_EXTRACT(filters, '$.is_jd_express') WHEN true THEN 1 ELSE 0  END AS is_jd_express,
                case  JSON_EXTRACT(filters, '$.is_second_hand') WHEN true THEN 1 ELSE 0  END AS is_second_hand,
                case  JSON_EXTRACT(filters, '$.is_new') WHEN true THEN 1 ELSE 0  END AS is_new,
                case  JSON_EXTRACT(filters, '$.is_to_pay') WHEN true THEN 1 ELSE 0  END AS is_to_pay
                FROM goods where status= 1;" >
              <!--查询的数据和数据库索引意义对应column 是查询的字段name 是solr索引对应的字段
              <field column="fid" name="fid"/>  因为已经使用As映射好了 不用加了-->
        </entity>
    </document> 
</dataConfig>

7.5 在阿里云上使用docker运行一个mysql


docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7


nvcat连接再把本地的数据库jd-shop上传到阿里云


7.6 把刚才修改和创建的两配置文件覆盖到solr配置

20200715203054737.png


重启solr 并查看控制台

20200715203141823.png


执行之后再查看数据


增量导入【略】

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
SQL JavaScript Java
springboot+springm vc+mybatis实现增删改查案例!
springboot+springm vc+mybatis实现增删改查案例!
27 0
|
4天前
|
数据采集 Web App开发 Java
Python 爬虫:Spring Boot 反爬虫的成功案例
Python 爬虫:Spring Boot 反爬虫的成功案例
|
16天前
|
自然语言处理 Java 索引
SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)
SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)
20 1
|
19天前
|
JSON Java Maven
Javaweb之SpringBootWeb案例之 SpringBoot原理的详细解析
Javaweb之SpringBootWeb案例之 SpringBoot原理的详细解析
45 0
Javaweb之SpringBootWeb案例之 SpringBoot原理的详细解析
|
19天前
|
XML 前端开发 JavaScript
SpringBoot之响应案例的详细解析
SpringBoot之响应案例的详细解析
13 0
|
23天前
|
Java 关系型数据库 MySQL
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
UWB (ULTRA WIDE BAND, UWB) 技术是一种无线载波通讯技术,它不采用正弦载波,而是利用纳秒级的非正弦波窄脉冲传输数据,因此其所占的频谱范围很宽。一套UWB精确定位系统,最高定位精度可达10cm,具有高精度,高动态,高容量,低功耗的应用。
34 0
一套java+ spring boot与vue+ mysql技术开发的UWB高精度工厂人员定位全套系统源码有应用案例
|
1月前
|
存储 Java 定位技术
SpringBoot轻松实现二维码条形码含源码案例
SpringBoot轻松实现二维码条形码含源码案例
26 1
|
2月前
|
JSON 前端开发 Java
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之Spring定义Jackson转换Null的方法和实现案例
【SpringBoot实战专题】「开发实战系列」全方位攻克你的技术盲区之Spring定义Jackson转换Null的方法和实现案例
46 0
|
3月前
day01_springboot综合案例(三)
day01_springboot综合案例
13 0
|
3月前
|
SQL
day01_springboot综合案例(二)
day01_springboot综合案例
49 0