nakama/backend/routes/postSearch.js

126 lines
3.9 KiB
JavaScript
Raw Normal View History

2025-11-03 20:35:01 +00:00
const express = require('express');
const router = express.Router();
const { authenticate } = require('../middleware/auth');
const { searchLimiter } = require('../middleware/rateLimiter');
const Post = require('../models/Post');
// Поиск постов по тексту и хэштегам
router.get('/', authenticate, searchLimiter, async (req, res) => {
try {
const { query, hashtag, page = 1, limit = 20 } = req.query;
let searchQuery = {};
// Применить whitelist настройки пользователя
if (req.user.settings.whitelist.noFurry) {
searchQuery.tags = { $ne: 'furry' };
}
if (req.user.settings.whitelist.onlyAnime) {
searchQuery.tags = 'anime';
}
if (req.user.settings.whitelist.noNSFW) {
searchQuery.isNSFW = false;
}
// Поиск по хэштегу
if (hashtag) {
searchQuery.hashtags = hashtag.toLowerCase();
}
// Полнотекстовый поиск
else if (query) {
searchQuery.$text = { $search: query };
} else {
return res.status(400).json({ error: 'Параметр query или hashtag обязателен' });
}
const posts = await Post.find(searchQuery)
.populate('author', 'username firstName lastName photoUrl')
.populate('mentionedUsers', 'username firstName lastName')
.populate('comments.author', 'username firstName lastName photoUrl')
.sort(query ? { score: { $meta: 'textScore' } } : { createdAt: -1 })
.limit(limit * 1)
.skip((page - 1) * limit)
.exec();
const count = await Post.countDocuments(searchQuery);
res.json({
posts,
totalPages: Math.ceil(count / limit),
currentPage: page
});
} catch (error) {
console.error('Ошибка поиска постов:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Получить популярные хэштеги
router.get('/trending-hashtags', authenticate, async (req, res) => {
try {
const { limit = 20 } = req.query;
const hashtags = await Post.aggregate([
{ $unwind: '$hashtags' },
{ $group: { _id: '$hashtags', count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{ $limit: parseInt(limit) }
]);
res.json({
hashtags: hashtags.map(h => ({
tag: h._id,
count: h.count
}))
});
} catch (error) {
console.error('Ошибка получения трендовых хэштегов:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
// Получить посты по хэштегу
router.get('/hashtag/:tag', authenticate, async (req, res) => {
try {
const { page = 1, limit = 20 } = req.query;
const hashtag = req.params.tag.toLowerCase();
const query = { hashtags: hashtag };
// Применить whitelist настройки пользователя
if (req.user.settings.whitelist.noFurry) {
query.tags = { $ne: 'furry' };
}
if (req.user.settings.whitelist.onlyAnime) {
query.tags = 'anime';
}
if (req.user.settings.whitelist.noNSFW) {
query.isNSFW = false;
}
const posts = await Post.find(query)
.populate('author', 'username firstName lastName photoUrl')
.populate('mentionedUsers', 'username firstName lastName')
.populate('comments.author', 'username firstName lastName photoUrl')
.sort({ createdAt: -1 })
.limit(limit * 1)
.skip((page - 1) * limit)
.exec();
const count = await Post.countDocuments(query);
res.json({
hashtag,
posts,
totalPages: Math.ceil(count / limit),
currentPage: page
});
} catch (error) {
console.error('Ошибка получения постов по хэштегу:', error);
res.status(500).json({ error: 'Ошибка сервера' });
}
});
module.exports = router;