结合了MySQL数据库、Elasticsearch和Redis,构建一个产品搜索和推荐系统
1. 数据库设置(MySQL)
首先,我们需要创建两个表来存储产品信息和产品类别信息。
CREATE DATABASE product_system;USE product_system;CREATE TABLE `categories` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE `products` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`description` TEXT,`price` DECIMAL(10, 2),`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);CREATE TABLE `product_categories` (`product_id` INT,`category_id` INT,PRIMARY KEY (`product_id`, `category_id`),FOREIGN KEY (`product_id`) REFERENCES `products`(`id`) ON DELETE CASCADE,FOREIGN KEY (`category_id`) REFERENCES `categories`(`id`) ON DELETE CASCADE
);
2. 安装依赖库
使用Composer安装Elasticsearch、Redis和数据库的依赖库。
composer require elasticsearch/elasticsearch predis/predis
composer require vlucas/phpdotenv # 用于环境变量管理
3. 配置环境变量
在项目根目录下创建一个.env文件,存储数据库和Elasticsearch的配置信息。
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=product_system
DB_USERNAME=root
DB_PASSWORD=yourpasswordELASTICSEARCH_HOST=127.0.0.1:9200
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
4. 创建数据库连接和Elasticsearch客户端
require 'vendor/autoload.php';use Elasticsearch\ClientBuilder;
use Predis\Client as RedisClient;
use PDO;// 加载环境变量
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();// 数据库连接
function getDatabaseConnection() {$dsn = "mysql:host=" . getenv('DB_HOST') . ";dbname=" . getenv('DB_DATABASE');return new PDO($dsn, getenv('DB_USERNAME'), getenv('DB_PASSWORD'));
}// Elasticsearch客户端
$elasticsearch = ClientBuilder::create()->setHosts([getenv('ELASTICSEARCH_HOST')])->build();// Redis客户端
$redis = new RedisClient(['scheme' => 'tcp','host' => getenv('REDIS_HOST'),'port' => getenv('REDIS_PORT'),
]);
5. Elasticsearch索引配置和数据同步
// 创建Elasticsearch索引
function createElasticsearchIndex($elasticsearch) {$params = ['index' => 'products','body' => ['mappings' => ['properties' => ['name' => ['type' => 'text'],'description' => ['type' => 'text'],'price' => ['type' => 'float'],]]]];$elasticsearch->indices()->create($params);
}// 同步数据库中的产品到Elasticsearch
function syncProductToElasticsearch($product, $elasticsearch) {$params = ['index' => 'products','id' => $product['id'],'body' => ['name' => $product['name'],'description' => $product['description'],'price' => $product['price'],]];$elasticsearch->index($params);
}// 从数据库获取产品数据
function getProductFromDatabase($productId, $db) {$stmt = $db->prepare("SELECT * FROM products WHERE id = :id");$stmt->execute(['id' => $productId]);return $stmt->fetch(PDO::FETCH_ASSOC);
}
6. 产品搜索与Redis缓存
function searchProducts($query, $elasticsearch, $redis) {$cacheKey = 'search_' . md5($query);// 从Redis中获取缓存数据if ($redis->exists($cacheKey)) {return json_decode($redis->get($cacheKey), true);}// 如果缓存未命中,则从Elasticsearch中搜索$params = ['index' => 'products','body' => ['query' => ['multi_match' => ['query' => $query,'fields' => ['name', 'description']]]]];$response = $elasticsearch->search($params);$results = array_map(function ($hit) {return $hit['_source'];}, $response['hits']['hits']);// 将搜索结果缓存到Redis$redis->setex($cacheKey, 3600, json_encode($results));return $results;
}
7. 添加和查询产品
// 添加新产品并同步到Elasticsearch
function addProduct($name, $description, $price, $db, $elasticsearch) {$stmt = $db->prepare("INSERT INTO products (name, description, price) VALUES (:name, :description, :price)");$stmt->execute(['name' => $name,'description' => $description,'price' => $price]);$productId = $db->lastInsertId();// 同步到Elasticsearch$product = getProductFromDatabase($productId, $db);syncProductToElasticsearch($product, $elasticsearch);
}// 通过关键词搜索产品
function searchAndDisplayProducts($query, $elasticsearch, $redis) {$products = searchProducts($query, $elasticsearch, $redis);foreach ($products as $product) {echo "Name: " . $product['name'] . "\n";echo "Description: " . $product['description'] . "\n";echo "Price: $" . $product['price'] . "\n";echo "-----------------------\n";}
}// 示例操作
$db = getDatabaseConnection();
addProduct('iPhone 14', 'Latest model of iPhone', 999.99, $db, $elasticsearch);
searchAndDisplayProducts('iPhone', $elasticsearch, $redis);
8. 完整项目结构
project-root/
│
├── .env
├── composer.json
├── vendor/
└── index.php
9. 运行项目
通过以下命令运行项目:
php -S localhost:8000
在浏览器中访问 http://localhost:8000,即可看到产品搜索结果。
这个项目展示了如何使用PHP结合MySQL、Elasticsearch和Redis,构建一个功能齐全的产品搜索和推荐系统。你可以根据自己的需要进一步扩展这个项目。
相关文章:
结合了MySQL数据库、Elasticsearch和Redis,构建一个产品搜索和推荐系统
1. 数据库设置(MySQL) 首先,我们需要创建两个表来存储产品信息和产品类别信息。 CREATE DATABASE product_system;USE product_system;CREATE TABLE categories (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(255) NOT NULL,created_at…...
白酒与素食:健康与美味的双重享受
在美食的世界里,白酒与素食的搭配仿佛是一场跨界的盛宴。豪迈白酒(HOMANLISM)的醇香与精致素食的清新,在不经意间交织出了一幅美妙的画卷,让人在品味中感受到健康与美味的双重享受。 素食,以其清淡、自然的…...
工厂现场多功能帮手,三防平板改善管理体验
随着制造业的智能化变革,信息化、自动化和智能化逐渐成为工厂管理的新常态。在这一波技术浪潮中,三防平板作为一种多功能的工作工具,正在逐步改善工厂现场的管理体验。 一、三防平板的定义与特点 三防平板,顾名思义,是…...
【git】问题解决---Failed to connect to github.com
场景 最近运行命令git push,git pull或者git clone的时候总会报如下错误 fatal: unable to access https://github.com/xxxxx/xxxxxx.git/: **Failed to connect to github.com** port 443 after 21052 ms: Couldnt connect to server原因 一般是网络配置原因造成的, 如果能…...
Java 中 String 类型的特点
在 Java 中,String 是一种常用且重要的数据类型,用于表示和处理字符序列。它有一些独特的特性和用法,使得它在开发中非常灵活和高效。以下是关于 String 类型的一些特点、特殊性、使用技巧以及注意事项。 1. String 的特点 1.1 不可变性 定…...
AddressUtils 、RegionUtils IP地址工具类
一、类展示 AddressUtils : /*** 获取地址类**/ Slf4j NoArgsConstructor(access AccessLevel.PRIVATE) public class AddressUtils {// 未知地址public static final String UNKNOWN "XX XX";public static String getRealAddressByIP(String ip) {i…...
牛客网SQL进阶134: 满足条件的用户的试卷总完成次数和题目总练习次数
满足条件的用户的试卷完成数和题目练习数_牛客题霸_牛客网 0 问题描述 基于用户信息表user_info、试卷信息表examination_info、试卷作答记录表exam_record、题目练习记录表practice_record,筛选出 高难度SQL试卷得分平均值大于80并且是7级的用户,统计他…...
机器学习:逻辑回归处理手写数字的识别
1、获取数据, 图像分割该数据有50行100列,每个数字占据20*20个像素点,可以进行切分,划分出训练集和测试集。 import numpy as np import pandas as pd import cv2 imgcv2.imread("digits.png")#读取文件 graycv2.cvtColor(img,cv2.COLOR_BGR2G…...
文件上传真hard
一、SpringMVC实现文件上传 1.1.项目结构 1.1.2 控制器方法 RequestMapping("/upload1.do")public ModelAndView upload1(RequestParam("file1") MultipartFile f1) throws IOException {//获取文件名称String originalFilename f1.getOriginalFilename(…...
精益管理|介绍一本专门研究防错法(Poka-Yoke)的书
在现代制造业中,如何确保产品在每个生产环节中不出现错误是企业追求的目标之一。而实现这一目标的关键技术之一就是防错法(Poka-Yoke)。作为一种简单而有效的精益管理、六西格玛管理工具,防错法帮助企业避免因人为错误或工艺不当导…...
面试题目:(4)给表达式添加运算符
目录 题目 代码 思路解析 例子 题目 题目 给定一个仅包含数字 0-9 的字符串 num 和一个目标值整数 target ,在 num 的数字之间添加 二元 运算符(不是一元)、- 或 * ,返回 所有能够得到 target 的表达式。1 < num.length &…...
[C#]将opencvsharp的Mat对象转成onnxruntime的inputtensor的3种方法
第一种方法:在创建tensor时候直接赋值改变每个tensor的值,以下是伪代码: var image new Mat(image_path);inpWidth image.Width;inpHeight image.Height;//将图片转为RGB通道Mat image_rgb new Mat();Cv2.CvtColor(image, image_rgb, Col…...
CTF入门教程(非常详细)从零基础入门到竞赛,看这一篇就够了!
一、CTF简介 CTF(Capture The Flag)中文一般译作夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。CTF起源于1996年DEFCON全球黑客大会,以代替之前黑客们通过互相发起真实攻击进行技术比拼的方式。…...
数据链路层 I(组帧、差错控制)【★★★★★】
(★★)代表非常重要的知识点,(★)代表重要的知识点。 为了把主要精力放在点对点信道的数据链路层协议上,可以采用下图(a)所示的三层模型。在这种三层模型中,不管在哪一段…...
悟空降世 撼动全球
文|琥珀食酒社 作者 | 积溪 一只猴子能值多少钱? 答案是:13个小目标 这两天 只要你家没有断网 一定会被这只猴子刷屏 它就是咱国产的3A游戏 《黑神话:悟空》 这只猴子到底有多火? 这么跟你说吧 茅台见了它都…...
Swoole 和 Java 哪个更有优势呢
Swoole 和 Java 各有优势,在性能上不能简单地说哪一个更好,需要根据具体的应用场景来分析。 Swoole 优势:高并发:Swoole 是一个基于 PHP 的异步、协程框架,专为高并发场景设计,适用于 I/O 密集型应用&…...
Salesforce 发布开源大模型 xGen-MM
xGen-MM 论文 在当今 AI 技术飞速发展的时代,一个新的多模态 AI 模型悄然崛起,引起了业界的广泛关注。这个由 Salesforce 推出的开源模型—— xGen-MM,正以其惊人的全能特性和独特优势,在 AI 领域掀起一阵旋风。那么,x…...
冒 泡 排 序
今天咱们单独拎出一小节来聊一聊冒泡排序昂 冒泡排序的核心思想就是:两两相邻的元素进行比较(理解思路诸君可看下图) 接下来我们上代码演示: 以上就是我们初步完成的冒泡排序,大家不难发现,不管数组中的元…...
采用先进的人工智能视觉分析技术,能够精确识别和分析,提供科学、精准的数据支持的智慧物流开源了。
智慧物流视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本可通过边缘计算技术…...
IAA游戏APP如何让合理地让用户观看更多广告,提高广告渗透率
广告变现已经成为休闲游戏开发者重要的收益方式之一,超50%国内休闲游戏已经采用广告变现的方式,游戏广告预算是游戏行业开发者广告变现的主要预算来源。 #深度好文计划#如何合理地提高广告渗透率? 广告渗透率能直接反映游戏中有广告行为用户…...
程序员,真要失业了:Claude Code新增/goal指令,一个命令,AI替你干完整个项目
最近,GitHub上发生了一件小事。 一个全美排名Top 5的软件工程师,发了一条帖子,只有三句话: “我用/goal重构了一个3万行的遗留项目,花了4小时。” “没有人盯着我,没有PR被拒,没有半夜爬起来看…...
Adafruit Bluefruit Playground:iOS与蓝牙开发板的物联网交互实战
1. 项目概述与核心价值 如果你手头有一块Adafruit的Circuit Playground Bluefruit或者CLUE开发板,想让它在你的iPhone或iPad上“活”起来,变成一个能远程控制彩灯、读取传感器数据甚至演奏音乐的智能玩具,那么Adafruit Bluefruit Playground …...
不只是安装:用MATLAB+RTL-SDR硬件支持包快速上手你的第一个无线信号接收项目
不只是安装:用MATLABRTL-SDR硬件支持包快速上手你的第一个无线信号接收项目 当你第一次将RTL-SDR设备插入电脑,安装完MATLAB硬件支持包后,那种既兴奋又迷茫的感觉可能还记忆犹新。硬件已经就绪,软件也已安装,但接下来该…...
STC8H高级PWM实战:用呼吸灯搞懂定时器配置,附完整代码和寄存器详解
STC8H高级PWM实战:从寄存器到呼吸灯的完整设计指南 在嵌入式开发领域,PWM(脉冲宽度调制)技术就像一位无声的魔术师,通过精确控制脉冲的宽度,它能让我们手中的LED灯实现从完全熄灭到最亮之间的任意亮度变化…...
cliclick 开发者指南:从源码编译到自定义Action开发
cliclick 开发者指南:从源码编译到自定义Action开发 【免费下载链接】cliclick macOS CLI tool for emulating mouse and keyboard events 项目地址: https://gitcode.com/gh_mirrors/cl/cliclick cliclick 是一款强大的 macOS 命令行工具,用于模…...
AI技能工程框架解析:从模块化设计到智能体构建实战
1. 项目概述:一个面向技能复现与创造的AI工具集最近在GitHub上看到一个挺有意思的项目,叫“skill-creator-pro”。光看这个名字,你可能会有点摸不着头脑,这到底是做什么的?是教人学技能的,还是生成技能的&a…...
多智能体协作框架Agentset:从原理到实战构建AI团队
1. 项目概述:当AI智能体开始“组队打怪”最近在AI应用开发圈里,一个词的热度持续攀升:智能体(Agent)。如果说大语言模型(LLM)是学会了“思考”的大脑,那么智能体就是具备了“感知-决…...
你还在手写提示词?:2024最稀缺的提示词自动化工作流(含可运行Python脚本+权重映射API)
更多请点击: https://intelliparadigm.com 第一章:Midjourney提示词编写的核心范式演进 早期提示词依赖直觉式描述(如“a cat”),而现代范式已转向结构化、分层可控的语义工程。当前主流实践将提示词解耦为三类要素&a…...
如何3分钟精准定位Windows热键冲突:Hotkey Detective深度技术解析
如何3分钟精准定位Windows热键冲突:Hotkey Detective深度技术解析 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective …...
论文详解:考虑人类移动日常节律的动态社区检测
论文详解:考虑人类移动日常节律的动态社区检测 文章目录 论文详解:考虑人类移动日常节律的动态社区检测 1. 论文基本信息 2. 摘要与核心贡献 2.1 研究背景 2.2 研究方法 2.3 核心贡献 3. 研究背景与问题提出 3.1 城市空间结构研究的重要性 3.2 传统静态社区检测的局限性 3.3 …...
