Nodejs如何实现类似zhihu的按照回答问题的赞同数来排序答案?

Nodejs如何实现类似zhihu的按照回答问题的赞同数来排序答案?

新手问题 sql or nosql来实现哪种比较好~

3 回复

Node.js 如何实现类似知乎的按照回答问题的赞同数来排序答案?

在构建类似于知乎的应用时,一个常见的需求是根据用户的投票(即赞同数)来对回答进行排序。这个问题可以通过使用关系型数据库(SQL)或非关系型数据库(NoSQL)来解决。下面我们将分别讨论这两种方法,并提供一些示例代码。

SQL 数据库

假设我们使用的是 MySQL 数据库,表结构可以设计为:

  • questions 表:

    • id (INT, 主键)
    • title (VARCHAR)
    • content (TEXT)
  • answers 表:

    • id (INT, 主键)
    • question_id (INT, 外键关联 questions.id)
    • content (TEXT)
    • votes (INT) // 赞同数
  • votes 表:

    • id (INT, 主键)
    • answer_id (INT, 外键关联 answers.id)
    • user_id (INT) // 投票用户ID
    • vote (TINYINT) // 投票值,1 表示赞同,-1 表示反对

为了获取按赞同数排序的答案,我们可以执行以下 SQL 查询:

SELECT a.id, a.content, COUNT(v.vote) AS vote_count
FROM answers a
LEFT JOIN votes v ON a.id = v.answer_id AND v.vote = 1
WHERE a.question_id = ?
GROUP BY a.id, a.content
ORDER BY vote_count DESC;

在 Node.js 中,你可以使用 mysql 模块来执行这个查询:

const mysql = require('mysql');

const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'your_database'
});

connection.connect();

const questionId = 1; // 假设这是我们要查询的问题ID

connection.query(`
  SELECT a.id, a.content, COUNT(v.vote) AS vote_count
  FROM answers a
  LEFT JOIN votes v ON a.id = v.answer_id AND v.vote = 1
  WHERE a.question_id = ?
  GROUP BY a.id, a.content
  ORDER BY vote_count DESC;
`, [questionId], (error, results) => {
  if (error) throw error;
  console.log(results);
});

connection.end();

NoSQL 数据库

假设我们使用 MongoDB 数据库,集合结构可以设计为:

  • questions 集合:

    • _id (ObjectId, 主键)
    • title (String)
    • content (String)
  • answers 集合:

    • _id (ObjectId, 主键)
    • question_id (ObjectId, 外键关联 questions._id)
    • content (String)
    • votes (Number) // 赞同数
  • votes 集合:

    • _id (ObjectId, 主键)
    • answer_id (ObjectId, 外键关联 answers._id)
    • user_id (ObjectId) // 投票用户ID
    • vote (Number) // 投票值,1 表示赞同,-1 表示反对

为了获取按赞同数排序的答案,我们可以使用聚合框架:

const MongoClient = require('mongodb').MongoClient;

const uri = "mongodb+srv://<username>:<password>@cluster0.mongodb.net/test?retryWrites=true&w=majority";
const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true });

client.connect(err => {
  const answerCollection = client.db("test").collection("answers");
  
  answerCollection.aggregate([
    { $match: { question_id: ObjectId(questionId) } },
    { $lookup: {
      from: "votes",
      localField: "_id",
      foreignField: "answer_id",
      as: "votes"
    }},
    { $unwind: "$votes" },
    { $match: { "votes.vote": 1 } },
    { $group: {
      _id: "$_id",
      content: { $first: "$content" },
      vote_count: { $sum: 1 }
    }},
    { $sort: { vote_count: -1 } }
  ]).toArray((err, result) => {
    if (err) throw err;
    console.log(result);
    client.close();
  });
});

通过上述两种方法,你可以在 Node.js 应用中实现类似知乎的按赞同数排序的回答功能。选择 SQL 还是 NoSQL 取决于你的具体需求和数据模型。


《redis入门指南》里有你这个问题的解决方法。貌似redis来做这个工作真的很不错。我更是新手,可以忽略。。。

要实现类似知乎中根据回答问题的赞同数对答案进行排序的功能,可以使用MongoDB这样的NoSQL数据库。这里假设你已经有一个包含问题和答案的数据结构,并且每个答案都有一个表示赞同数的字段。

示例数据结构

{
    "question": {
        "_id": "1",
        "title": "如何学习编程?",
        "answers": [
            {
                "_id": "1",
                "content": "多动手实践。",
                "upvotes": 50
            },
            {
                "_id": "2",
                "content": "多看书籍。",
                "upvotes": 30
            },
            {
                "_id": "3",
                "content": "参加线上课程。",
                "upvotes": 40
            }
        ]
    }
}

实现思路

  1. 获取问题的所有答案:查询该问题下的所有答案。
  2. 按赞同数排序:使用MongoDB的聚合框架(Aggregation Framework)对结果进行排序。

示例代码

首先确保你已经安装了mongoose库,用于操作MongoDB。

npm install mongoose

然后创建一个简单的Node.js脚本:

const mongoose = require('mongoose');

// 连接MongoDB
mongoose.connect('mongodb://localhost:27017/mydatabase', { useNewUrlParser: true, useUnifiedTopology: true });

// 定义模式
const AnswerSchema = new mongoose.Schema({
    content: String,
    upvotes: Number
});

const QuestionSchema = new mongoose.Schema({
    title: String,
    answers: [AnswerSchema]
});

const Question = mongoose.model('Question', QuestionSchema);

async function sortAnswersByUpvotes(questionId) {
    try {
        const question = await Question.findById(questionId).populate('answers');
        
        if (!question) {
            console.log('未找到该问题');
            return;
        }

        // 对答案数组进行排序
        question.answers.sort((a, b) => b.upvotes - a.upvotes);

        console.log(question);
    } catch (error) {
        console.error(error);
    }
}

// 调用函数
sortAnswersByUpvotes("1");

解释

  • 使用Mongoose定义问题和答案的模式。
  • sortAnswersByUpvotes函数通过问题ID查找问题并排序答案。
  • 答案数组使用JavaScript的sort()方法按赞同数降序排列。

这种方法简单直接,适用于中小型应用。如果需要处理大量数据,可能需要优化数据库索引或考虑更复杂的查询策略。

回到顶部