基于MongoDB Book模型实现用户心愿书单对比与书籍推荐
实现用户心愿书单对比与书籍推荐功能
需求概述
需要完成以下核心功能:
- 对比两位用户的心愿书单,筛选出双方共同加入心愿单的书籍
- 将用户A心愿单中独有的书籍推荐给用户B,用户B心愿单中独有的书籍推荐给用户A
举个直观例子:
- 用户A心愿单:
['item1', 'item2', 'item3', 'item4'] - 用户B心愿单:
['item2', 'item4', 'item5', 'item6'] - 共同书籍:
item2、item4 - 给B推荐:
item1、item3 - 给A推荐:
item5、item6
数据库模型修正说明
你提供的Book模型中,wishListedBy字段存在嵌套数组的错误定义,会导致存储结构异常,无法正确关联用户与心愿书籍。修正后的字段定义如下:
wishListedBy: [ { type: mongoose.Schema.Types.ObjectId, ref: "User", }, ],
实现思路与代码示例
1. 获取指定用户的心愿书单
编写函数根据用户ID查询其所有心愿书籍:
async function getUserWishList(userId) { try { // 查询该用户的心愿书籍,可按需关联书籍所有者信息 const wishListBooks = await Book.find({ wishListedBy: userId }) .populate('owner', 'name email') // 可选:关联所有者的名称、邮箱 .exec(); return wishListBooks; } catch (err) { console.error('获取心愿单失败:', err); throw err; } }
2. 对比心愿单并生成推荐
编写对比函数,计算共同书籍与互相推荐的书籍:
async function generateWishListRecommendations(userIdA, userIdB) { // 获取两个用户的心愿书单 const wishListA = await getUserWishList(userIdA); const wishListB = await getUserWishList(userIdB); // 将书籍转为以ID为键的映射,提升查找效率 const bookMapA = new Map(wishListA.map(book => [book._id.toString(), book])); const bookMapB = new Map(wishListB.map(book => [book._id.toString(), book])); // 筛选共同书籍 const commonBooks = wishListA.filter(book => bookMapB.has(book._id.toString())); // 给B推荐的书籍:A有但B没有的 const recommendationsForB = wishListA.filter(book => !bookMapB.has(book._id.toString())); // 给A推荐的书籍:B有但A没有的 const recommendationsForA = wishListB.filter(book => !bookMapA.has(book._id.toString())); return { commonBooks, recommendationsForA, recommendationsForB }; }
3. 使用示例
// 假设用户A的ID为'user123',用户B的ID为'user456' generateWishListRecommendations('user123', 'user456') .then(result => { console.log('共同书籍:', result.commonBooks.map(b => b.bookName)); console.log('给A的推荐:', result.recommendationsForA.map(b => b.bookName)); console.log('给B的推荐:', result.recommendationsForB.map(b => b.bookName)); }) .catch(err => console.error('生成推荐失败:', err));
补充优化点
- 性能优化:查询时可只返回必要字段,比如
Book.find({ wishListedBy: userId }, '_id bookName author'),减少数据传输量 - 个性化推荐:可结合书籍的
subject、branch字段,优先推荐同专业/同领域的书籍 - 有效性过滤:添加
isSold: false条件,避免推荐已售出的书籍
内容的提问来源于stack exchange,提问作者Aashish Adhikari
相关产品推荐
相关产品推荐

