基于Mongoose实现用户间水果供需完美匹配的技术问询
使用Mongoose实现用户完美匹配
需求定义
完美匹配指:用户A的fruitiwant数组中至少有一个水果在用户B的fruitihave数组里,同时用户B的fruitiwant数组中至少有一个水果在用户A的fruitihave数组里。
1. 定义Mongoose Schema
首先创建用户数据模型:
const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ username: { type: String, required: true, unique: true }, fruitiwant: [{ type: String, required: true }], fruitihave: [{ type: String, required: true }] }); const User = mongoose.model('User', userSchema);
2. 实现完美匹配查询
使用MongoDB聚合管道从数据库层面完成双向匹配筛选,效率更高:
async function getPerfectMatches() { const matchedPairs = await User.aggregate([ // 关联自身用户集合,筛选匹配对象 { $lookup: { from: 'users', let: { currentUserId: '$_id', currentWant: '$fruitiwant', currentHave: '$fruitihave' }, pipeline: [ // 排除用户自身匹配 { $match: { $expr: { $ne: ['$_id', '$$currentUserId'] } } }, // 核心匹配条件:双向满足水果需求与拥有的交集 { $match: { $expr: { $and: [ { $gt: [{ $size: { $setIntersection: ['$$currentWant', '$fruitihave'] } }, 0] }, { $gt: [{ $size: { $setIntersection: ['$fruitiwant', '$$currentHave'] } }, 0] } ] } } }, // 只保留需要返回的字段 { $project: { username: 1, fruitiwant: 1, fruitihave: 1, _id: 0 } } ], as: 'perfectMatches' } }, // 过滤掉无匹配结果的用户 { $match: { 'perfectMatches.0': { $exists: true } } }, // 优化输出格式 { $project: { username: 1, fruitiwant: 1, fruitihave: 1, perfectMatches: 1, _id: 0 } } ]); // 返回格式化后的JSON结果 return JSON.stringify(matchedPairs, null, 2); } // 调用示例 getPerfectMatches() .then(result => console.log(result)) .catch(err => console.error('查询失败:', err));
3. 可选:去重匹配对
如果需要避免重复返回(比如A→B和B→A只保留一组),可以在聚合管道末尾添加以下步骤:
// 接上面的聚合管道,添加在最后一个$project之后 { $unwind: '$perfectMatches' }, { $group: { _id: { // 按用户名排序生成唯一标识,避免重复 $cond: [ { $lt: ['$username', '$perfectMatches.username'] }, { userA: '$username', userB: '$perfectMatches.username' }, { userA: '$perfectMatches.username', userB: '$username' } ] }, userADetails: { $first: { username: '$username', fruitiwant: '$fruitiwant', fruitihave: '$fruitihave' } }, userBDetails: { $first: '$perfectMatches' } } }, { $project: { _id: 0, perfectPair: ['$userADetails', '$userBDetails'] } }
内容的提问来源于stack exchange,提问作者Vit Ruve
相关产品推荐
相关产品推荐

