Nodejs博客文章被查看次数如何设计?

Nodejs博客文章被查看次数如何设计?

在cnodejs中,查看某个话题时,只要页面刷新一次,该话题的查看次数就增加了一次;这样做感觉不是很合理,有没有一个好的方法,同一个用户多次点击某个话题,该话题的被查看次数只加1

7 回复

Node.js 博客文章被查看次数的设计

在设计一个博客系统时,记录文章的被查看次数是一个常见的需求。然而,直接在每次页面加载时都增加查看次数可能会导致不准确的结果,尤其是在用户多次刷新页面的情况下。为了确保数据的准确性,我们可以采用一些策略来优化这一过程。

设计思路

  1. 唯一标识符:使用用户的唯一标识符(如用户ID或IP地址)来记录每个用户的访问情况。
  2. 缓存机制:利用缓存机制来减少数据库的读写操作。
  3. 定时任务:定期更新数据库中的查看次数统计。

示例代码

假设我们使用的是 Express 框架,并且有一个 MongoDB 数据库来存储文章信息。

  1. 定义模型
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const ArticleSchema = new Schema({
    title: String,
    content: String,
    views: { type: Number, default: 0 },
    lastViewed: { type: Date, default: Date.now }
});

module.exports = mongoose.model('Article', ArticleSchema);
  1. 中间件处理

在 Express 中间件中,我们可以检查用户是否已经访问过该文章:

const express = require('express');
const Article = require('./models/Article');

const app = express();

app.get('/article/:id', async (req, res) => {
    const { id } = req.params;
    const article = await Article.findById(id);

    // 检查是否已经有记录
    if (!article.viewedBy || !article.viewedBy.includes(req.ip)) {
        // 更新浏览次数
        article.views += 1;
        article.viewedBy.push(req.ip);
        await article.save();
    }

    res.render('article', { article });
});
  1. 定时任务更新

使用 node-cron 或其他定时任务库来定期更新数据库中的统计数据:

const cron = require('node-cron');

cron.schedule('0 * * * *', async () => {
    const articles = await Article.find({});
    
    for (let article of articles) {
        // 假设每天只统计前一天的数据
        const yesterday = new Date();
        yesterday.setDate(yesterday.getDate() - 1);
        
        if (article.lastViewed < yesterday) {
            article.views += article.viewedBy.length;
            article.viewedBy = [];
            await article.save();
        }
    }
});

总结

通过使用唯一标识符、缓存机制以及定时任务,我们可以有效地管理博客文章的被查看次数。这种方法不仅可以避免重复计数的问题,还可以减轻数据库的压力,提高系统的整体性能。


mahua ##MaHua是什么? 一个在线编辑markdown文档的编辑器

向Mac下优秀的markdown编辑器mou致敬

##MaHua有哪些功能?

  • 方便的导入导出功能
    • 直接把一个markdown的文本文件拖放到当前这个页面就可以了
    • 导出为一个html格式的文件,样式一点也不会丢失
  • 编辑和预览同步滚动,所见即所得(右上角设置)
  • VIM快捷键支持,方便vim党们快速的操作 (右上角设置)
  • 强大的自定义CSS功能,方便定制自己的展示
  • 有数量也有质量的主题,编辑器和预览区域
  • 完美兼容Github的markdown语法
  • 预览区域代码高亮
  • 所有选项自动记忆

##有问题反馈 在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流

##捐助开发者 在兴趣的驱动下,写一个免费的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(右上角的爱心标志,支持支付宝和PayPal捐助),没钱捧个人场,谢谢各位。

##感激 感谢以下的项目,排名不分先后

##关于作者

  var ihubo = {
    nickName : "草依山",
    site : "http://jser.me"
  }

准备一个数组,存放看过的用户名,统计数组长度得到看过文章的人数。对于未注册用户没办法精确统计,只好存他的ip或者sessionID了,都不靠谱

1.1. 版本检测

route hall.hallHandler.versionCheck

Request

Key Type length require comments
vcode int Y 客户端版本号
pcode int Y 升级包版本号
dvecodestring 64 Y 设备号

<script>alert(“hi”);</script>

在当前用户cookie中记下本话题的ID,这样下次如果当前用户已经看过本话题了(从cookie知道),那么查看数就不加一了。 一般网站统计器都是按cookie来分辩单个用户的。

PS:session也是cookie实现的。

在设计一个Node.js博客系统时,处理文章被查看次数的需求通常需要考虑两个关键点:确保计数准确且防止重复计数。对于同一用户多次点击某个文章,查看次数只增加一次的要求,可以通过设置访问记录或者使用一些缓存机制来实现。

以下是一个简单的实现方式,使用Redis作为缓存来存储用户的访问记录:

  1. 首先安装必要的依赖包:
npm install express redis
  1. 在你的Node.js应用中引入这些模块,并配置Redis客户端:
const express = require('express');
const redis = require('redis');
const client = redis.createClient();
client.on('error', (err) => {
    console.log(`Error ${err}`);
});
const app = express();
  1. 实现路由来处理文章查看逻辑:
app.get('/article/:id', (req, res) => {
    const articleId = req.params.id;
    
    // 检查用户是否已经访问过这篇文章
    client.sismember('viewed_users', `${req.ip}-${articleId}`, (err, viewed) => {
        if (err) throw err;

        if (!viewed) {
            // 用户尚未访问过此文章,增加查看次数
            client.get(articleId, (err, count) => {
                if (err) throw err;
                
                const newCount = count ? parseInt(count) + 1 : 1;
                client.set(articleId, newCount);
                
                // 将当前用户添加到已查看集合中
                client.sadd('viewed_users', `${req.ip}-${articleId}`);
            });
        }

        // 返回文章详情或直接返回查看次数
        res.send(`Article ${articleId} has been viewed ${newCount} times`);
    });
});

在这个例子中,我们使用了redis作为存储用户访问信息的工具。每当一个用户访问一篇文章时,我们检查该用户(通过IP地址标识)是否已经访问过该文章。如果没有,则增加文章的查看次数,并将用户记录下来,避免重复计数。

这种方法可以有效地解决重复计数的问题,同时利用Redis的高性能来优化读写操作。当然,在实际生产环境中,可能还需要考虑更多的因素,如分布式环境下的用户识别等。

回到顶部