Spaces:
Sleeping
Sleeping
File size: 2,156 Bytes
0f8617c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | const User = require('../models/User');
const getRecommendations = async (req, res) => {
try {
const { budget, lat, lng, specialty } = req.query;
// 1. Fetch photographers with matching specialty
let query = { role: 'photographer' };
if (specialty) {
query.specialty = { $regex: specialty, $options: 'i' };
}
const photographers = await User.find(query).select('-password');
// 2. Scoring Algorithm
const scoredPhotographers = photographers.map(pg => {
let score = 0;
// Rating Score (0-40 points)
score += (pg.rating || 0) * 8; // rating 5.0 -> 40 points
// Budget Score (0-30 points)
if (budget) {
const userBudget = parseFloat(budget);
if (pg.price <= userBudget) {
score += 30; // Within budget
} else if (pg.price <= userBudget * 1.5) {
score += 15; // Slightly over budget
}
} else {
score += 20; // Default budget score
}
// Proximity Score (0-30 points) - Placeholder for now
// In a real app, use geodist or similar
if (lat && lng && pg.location && pg.location.coordinates) {
const dist = Math.sqrt(
Math.pow(pg.location.coordinates[1] - parseFloat(lat), 2) +
Math.pow(pg.location.coordinates[0] - parseFloat(lng), 2)
);
if (dist < 0.1) score += 30; // Very close
else if (dist < 1) score += 15; // Moderately close
} else {
score += 15; // Default proximity score
}
return { ...pg.toObject(), recommendationScore: score };
});
// 3. Sort by score and return top results
const sorted = scoredPhotographers.sort((a, b) => b.recommendationScore - a.recommendationScore);
res.json(sorted.slice(0, 5));
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = { getRecommendations };
|