Redis實(shí)現(xiàn)用戶關(guān)注的項(xiàng)目實(shí)踐
在實(shí)現(xiàn)社交網(wǎng)絡(luò)功能中,實(shí)現(xiàn)互相關(guān)注是必不可少的。在這里,我們將使用Redis來實(shí)現(xiàn)這個(gè)功能,前端使用Vue框架實(shí)現(xiàn)。
功能要求
我們需要實(shí)現(xiàn)以下幾個(gè)功能:
- 用戶能夠關(guān)注其他用戶
- 用戶能夠取消關(guān)注其他用戶
- 用戶能夠查看自己關(guān)注的人和被誰關(guān)注
- 在用戶的主頁上,能夠顯示關(guān)注和被關(guān)注的數(shù)量
Redis存儲(chǔ)結(jié)構(gòu)設(shè)計(jì)
我們使用Redis的set數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)用戶關(guān)注的人和被關(guān)注的人。具體來說,每個(gè)用戶都有一個(gè)following和followers屬性,分別表示該用戶關(guān)注的人和被誰關(guān)注。然后在Redis中使用set類型來存儲(chǔ)這些關(guān)注信息,在set中,我們將每個(gè)關(guān)注對(duì)象的id存儲(chǔ)下來,方便后續(xù)的查詢。
后端實(shí)現(xiàn)
添加關(guān)注
我們需要通過API來讓用戶實(shí)現(xiàn)添加關(guān)注和取消關(guān)注。下面是添加關(guān)注的API代碼:
// 添加關(guān)注
router.post('/followers/:id', async (req, res) => {
try {
const followerId = req.user.id;
const followingId = req.params.id;
// 獲取被關(guān)注的用戶和關(guān)注該用戶的用戶
const following = await User.findById(followingId);
const follower = await User.findById(followerId);
// 添加關(guān)注對(duì)象
await redis.sadd(`user:${followerId}:following`, followingId);
await redis.sadd(`user:${followingId}:followers`, followerId);
res.json({ message: `You are now following ${following.username}` });
} catch (error) {
console.error(error.message);
res.status(500).send('Server Error');
}
});
在這個(gè)代碼中,我們使用了redis.sadd方法將關(guān)注對(duì)象的id添加到set中。
取消關(guān)注
接下來是取消關(guān)注的API代碼:
// 取消關(guān)注
router.delete('/followers/:id', async (req, res) => {
try {
const followerId = req.user.id;
const followingId = req.params.id;
// 獲取被取消關(guān)注的用戶和取消關(guān)注該用戶的用戶
const following = await User.findById(followingId);
const follower = await User.findById(followerId);
// 刪除關(guān)注對(duì)象
await redis.srem(`user:${followerId}:following`, followingId);
await redis.srem(`user:${followingId}:followers`, followerId);
res.json({ message: `You have unfollowed ${following.username}` });
} catch (error) {
console.error(error.message);
res.status(500).send('Server Error');
}
});
這個(gè)代碼與添加關(guān)注的代碼類似,只是使用了redis.srem方法來將關(guān)注對(duì)象的id從set中刪除。
查看關(guān)注對(duì)象
最后,我們需要實(shí)現(xiàn)查看關(guān)注對(duì)象的API。這個(gè)API需要分別獲取關(guān)注和被關(guān)注的set,然后將id轉(zhuǎn)換為用戶對(duì)象。
// 獲取關(guān)注和粉絲
router.get('/followers', async (req, res) => {
try {
const userId = req.user.id;
// 獲取關(guān)注和被關(guān)注的set
const [following, followers] = await Promise.all([
redis.smembers(`user:${userId}:following`),
redis.smembers(`user:${userId}:followers`),
]);
// 將id轉(zhuǎn)換為用戶對(duì)象
const followingUsers = await Promise.all(
following.map((id) => User.findById(id))
);
const followerUsers = await Promise.all(
followers.map((id) => User.findById(id))
);
res.json({ following: followingUsers, followers: followerUsers });
} catch (error) {
console.error(error.message);
res.status(500).send('Server Error');
}
});
前端實(shí)現(xiàn)
在前端中,我們使用Vue框架來實(shí)現(xiàn)。需要提供以下功能:
- 用戶可以通過點(diǎn)擊按鈕來添加和取消關(guān)注操作
- 用戶的主頁可以顯示關(guān)注和被關(guān)注的數(shù)量
添加關(guān)注和取消關(guān)注操作
在Vue中,我們可以使用@click監(jiān)聽用戶點(diǎn)擊事件,并在方法中發(fā)送API請(qǐng)求來進(jìn)行添加和取消關(guān)注。下面是代碼示例:
<!-- 添加關(guān)注 --> <button @click="followUser(user._id)" v-if="!isFollowing(user._id)">關(guān)注</button> <!-- 取消關(guān)注 --> <button @click="unfollowUser(user._id)" v-else>取消關(guān)注</button>
methods: {
// 添加關(guān)注
async followUser(id) {
await axios.post(`/api/followers/${id}`);
// 更新關(guān)注狀態(tài)
this.isFollowingUsers[id] = true;
},
// 取消關(guān)注
async unfollowUser(id) {
await axios.delete(`/api/followers/${id}`);
// 更新關(guān)注狀態(tài)
this.isFollowingUsers[id] = false;
},
// 判斷是否關(guān)注
isFollowing(id) {
return this.isFollowingUsers[id];
}
}
在這個(gè)代碼中,我們使用了isFollowingUsers對(duì)象來存儲(chǔ)所有用戶的關(guān)注狀態(tài)。
顯示關(guān)注和被關(guān)注數(shù)量
為了在用戶的主頁上顯示關(guān)注和被關(guān)注的數(shù)量,我們需要在后端添加相應(yīng)的API,并在前端調(diào)用數(shù)據(jù)顯示。下面是相關(guān)代碼:
// 獲取關(guān)注和粉絲數(shù)量
router.get('/followers/count', async (req, res) => {
try {
const userId = req.user.id;
// 獲取關(guān)注和被關(guān)注數(shù)量
const [followingCount, followerCount] = await Promise.all([
redis.scard(`user:${userId}:following`),
redis.scard(`user:${userId}:followers`),
]);
res.json({ followingCount, followerCount });
} catch (error) {
console.error(error.message);
res.status(500).send('Server Error');
}
});
<!-- 顯示關(guān)注和被關(guān)注數(shù)量 -->
<div>
<p>關(guān)注 {{followingCount}}</p>
<p>被關(guān)注 {{followerCount}}</p>
</div>
在這個(gè)代碼中,我們使用了redis.scard方法來獲取set的數(shù)量。
總結(jié)
以上就是使用Redis實(shí)現(xiàn)互相關(guān)注功能的全部?jī)?nèi)容。通過使用Redis的set數(shù)據(jù)結(jié)構(gòu)來存儲(chǔ)關(guān)注對(duì)象,方便高效地進(jìn)行添加和取消關(guān)注操作。同時(shí),在前端中使用Vue框架實(shí)現(xiàn)了可交互的關(guān)注和取消關(guān)注按鈕,并在用戶主頁上顯示了關(guān)注和被關(guān)注的數(shù)量。
到此這篇關(guān)于Redis實(shí)現(xiàn)用戶關(guān)注的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)Redis 用戶關(guān)注內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
CentOS8.4安裝Redis6.2.6的詳細(xì)過程
本文給大家介紹CentOS8.4安裝Redis6.2.6的詳細(xì)過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-11-11
關(guān)于Redis?bigkeys命令會(huì)阻塞問題的解決
這篇文章主要介紹了關(guān)于Redis?bigkeys命令會(huì)阻塞問題的解決,今天分享一次Redis引發(fā)的線上事故,避免再次踩雷,實(shí)現(xiàn)快速入門,需要的朋友可以參考下2023-03-03
Redis migrate數(shù)據(jù)遷移工具的使用教程
這篇文章主要給大家介紹了關(guān)于Redis migrate數(shù)據(jù)遷移工具的使用教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Caffeine實(shí)現(xiàn)類似redis的動(dòng)態(tài)過期時(shí)間設(shè)置示例
這篇文章主要為大家介紹了Caffeine實(shí)現(xiàn)類似redis的動(dòng)態(tài)過期時(shí)間示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
redis實(shí)現(xiàn)簡(jiǎn)單分布式鎖
這篇文章主要介紹了redis實(shí)現(xiàn)簡(jiǎn)單分布式鎖,文中通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下2013-09-09

