Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions src/domains/keyword/keywordController.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,36 @@ const getArticlesByCompany = async (req, res) => {
};

const getArticleCounts = async (req, res) => {
const { keyword } = req.params;
console.log('개수 조회 키워드: ', keyword);
const keywords = req.query.keywords ? req.query.keywords.split(',') : [];

if (!keyword) {
return res.status(400).json({ error: "Keyword is required" });
if (keywords.length === 0) {
return res.status(400).json({ error: "At least one keyword is required" });
}

console.log('개수 조회 키워드: ', keywords);

try {
const count = await fetchArticleCounts(keyword);
if (count === null) {
return res.status(404).json({ error: "Keyword not found in stats" });
}
// 여러 키워드를 병렬로 조회
const results = await Promise.all(
keywords.map(keyword => fetchArticleCounts(keyword))
);

// 응답 데이터 정리
const response = Object.fromEntries(
keywords.map((keyword, index) => [
keyword,
results[index] || { error: "Keyword not found in stats" }
])
);

res.status(200).json(count);
res.status(200).json(response);
} catch (error) {
console.error("Error fetching article count:", error.message);
res.status(500).json({ error: "Failed to fetch article count" });
console.error("Error fetching article counts:", error.message);
res.status(500).json({ error: "Failed to fetch article counts" });
}
};


const getKeywords = async (req, res) => {
try {
const keywords = await fetchKeywords();
Expand Down
35 changes: 13 additions & 22 deletions src/domains/keyword/keywordService.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,36 +63,26 @@ const fetchArticlesByCompany = async (keyword, company) => {

const fetchArticleCounts = async (keyword) => {
console.log(`[fetchArticlesCounts] 조회 키워드: ${keyword}`);

const key = "keyword:stats";
const companyCntKey = `keyword:${keyword}:company_stats`;

// keyword:stats 값 조회
try {
// keyword:stats 키 존재 여부 확인
const companyKeys = await redisClient.keys(key);
if (!companyKeys) {
console.log(`Key does not exist: ${key}`);
// 키가 존재하는지 확인 (`keys()` 대신 `hExists()` 사용하여 성능 최적화)
const exists = await redisClient.hExists(key, keyword);
if (!exists) {
console.log(`Keyword not found in stats: ${keyword}`);
return null;
}

// 키의 데이터 타입 확인
const type = await redisClient.type(key);

let totalCount = null;
if (type === "hash") {
// 특정 필드 값 조회
totalCount = await redisClient.hGet(key, keyword);
if (!totalCount) {
console.log(`keyword does not exist: ${keyword}`);
return null;
}
} else {
throw new Error(`Unsupported totalCount type: ${type}`);
// 특정 필드 값 조회
const totalCount = await redisClient.hGet(key, keyword);
if (!totalCount) {
console.log(`Keyword does not exist: ${keyword}`);
return null;
}

// keyword:${keyword}:company_stats값 조회
// == 키워드에 대한 언론사 별 기사 개수 조회

// 언론사별 기사 개수 조회
const mediaCounts = (await redisClient.hGetAll(companyCntKey)) || {};

console.log(`키워드 전체 개수: ${totalCount}`);
Expand All @@ -101,14 +91,15 @@ const fetchArticleCounts = async (keyword) => {
return {
keyword,
totalCount: parseInt(totalCount, 10),
mediaCounts: mediaCounts,
mediaCounts,
};
} catch (err) {
console.error("Error fetching article counts:", err);
throw err;
}
};


const fetchKeywords = async () => {
try {
const keywords = await redisClient.sMembers('keywords'); // 'keywords' 키의 데이터를 가져옴
Expand Down