Я пытаюсь составить запрос, чтобы найти подписчиков пользователя в таблице «Follow», затем просмотреть любимые категории каждого подписчика в таблице «UserCategories», затем найти вопросы в этих категориях, а затем найти вопросы, которые у них есть.спросил, ответил или прокомментировал соответственно таблицы «вопрос», «ответ» или «комментарий» и их категории, затем найдите все вопросы в этих категориях, а затем верните все вопросы.Возможно ли это?
Мои таблицы -
CREATE TABLE follow (
"followingUserId" INTEGER REFERENCES account(id),
"followedUserId" INTEGER REFERENCES account(id)
);
CREATE TABLE userCategory (
"accountId" INTEGER REFERENCES account(id),
"categoryId" INTEGER REFERENCES category(id),
PRIMARY KEY ("accountId", "categoryId")
);
CREATE TABLE question (
id SERIAL PRIMARY KEY,
body TEXT,
"accountId" INTEGER,
"categoryId" INTEGER,
token TSVECTOR,
FOREIGN KEY ("accountId") REFERENCES account(id),
FOREIGN KEY ("categoryId") REFERENCES category(id)
);
CREATE TABLE answer (
id SERIAL PRIMARY KEY,
body TEXT,
"questionId" INTEGER,
"accountId" INTEGER,
FOREIGN KEY ("questionId") REFERENCES question(id),
FOREIGN KEY ("accountId") REFERENCES account(id)
);
CREATE TABLE comment (
id SERIAL PRIMARY KEY,
body TEXT,
"accountId" INTEGER,
"questionId" INTEGER,
"answerId" INTEGER,
FOREIGN KEY ("accountId") REFERENCES account(id),
FOREIGN KEY ("questionId") REFERENCES question(id),
FOREIGN KEY ("answerId") REFERENCES answer(id)
)
В настоящее время я могу отвечать на вопросы из любимых категорий пользователей и его / ее подписчиков с отдельными запросами и некоторыми связанными обещаниями.Как вы можете себе представить, это становится все более и более сложным, когда я углубляюсь в цепочки Promise.Производительность с точки зрения затрат, я уверен, что мой нынешний метод ужасен.
Вот как я делаю atm-
//recommended questions for users based on their categories
static getRecommendedQsByCates({ accountId }) {
return new Promise((resolve, reject) => {
pool.query(
`SELECT id, body, question."categoryId", question."accountId" FROM question INNER JOIN userCategory
ON question."categoryId"=userCategory."categoryId"
WHERE userCategory."accountId"=$1`,
[accountId],
(err, res) => {
if (err) return reject(err)
resolve({ questions: res.rows })
}
)
})
}
//recommended-questions route based on users liked categories,
//and the categories liked by the people user follows.
//get users liked categories, and the questions in those categories
//push them into a queue.
//if no categories exists, then return all questions
//then, find the categories liked by all the followed users
//find questions belonging to those categories
//push those questions into the queue
//remove duplicates questions
//return one final array
router.get(
'/questions',
passport.authenticate('jwt', { session: false }),
(req, res, next) => {
const { id } = req.user
let aggregateRecommendedQuestions = []
let dupsRemoved = []
Question.getRecommendedQsByCates({ accountId: id })
.then(({ questions }) => {
if (questions && questions.length > 0) {
questions.map(question => aggregateRecommendedQs.push(question))
} else {
Question.getAllQuestions().then(({ questions }) => {
if (questions && questions.length > 0) {
res.json({
type: 'FOUND',
message: 'All questions',
questions: questions
})
} else {
res.json({
type: 'NO_QUESTIONS',
message:
'No question has been asked yet. Be the first to ask a meaningful question.'
})
}
}).catch(err => next(err))
}
})
.then(() => {
Follow.findFollowed({ accountId: id }).then(resp => {
resp.map(({ followed }) => {
Promise.all([
UserCategory.getUserCategories({ accountId: followed })
]).then(resp => {
resp.map(({ categories }) => {
// console.log(categories)
categories.map(({ categoryId }) => {
Promise.all([Question.getQuestionsByCategory({ categoryId })])
.then(resp => {
resp.map(({ questions }) => {
aggregateRecommendedQs.push(questions[0])
})
})
.then(() => {
//remove duplicates
dupsRemoved = Object.values(
aggregateRecommendedQs.reduce(
(acc, curr) => ((acc[`${curr.body}`] = curr), acc),
{}
)
)
})
})
})
})
})
})
})
.catch(err => next(err))
setTimeout(() => {
res.json({
type: 'FOUND',
message:
'Here are some questions based on the users and his/hers followed users categories',
questions: dupsRemoved
})
}, 100)
}
)
После всего этого, я даже еще не изучил все "questionId" в ответе и таблицы комментариев дляпоследователи.Пока это работает, но мне нужен лучший способ найти все вопросы.
Можно ли построить SQL-запрос, который делает все это или, по крайней мере, приблизить меня, не выполняя все обещания?