.NET 雲原生架構師訓練營(模組二 基礎鞏固 MongoDB 問答系統)–學習筆記

2.5.6 MongoDB — 問答系統

  • MongoDB 資料庫設計
  • API 實現概述

MongoDB 資料庫設計

設計優化

  • 內嵌(mongo)還是引用(mysql)
  • 數據一致性

範式:將數據分散到不同的集合;反範式:使用內嵌文檔

在範式化的情況下需要在進行多次查詢再拼裝數據,或者使用 lookup,即跨表查詢;反範式化的情況下可以直接查出相關數據

更適合內嵌 更適合引用
子文檔較小 子文檔較大
數據不會定期改變 數據經常改變
最終數據一致即可 中間階段數據必須一致
文檔數據小幅增加 文檔數據大幅增加
數據通過需要執行二次查詢才能獲得 數據通常不包含在結果中
快速讀取 快速寫入

需求

  • 查詢所有問題(根據標籤查詢,按發布時間,瀏覽數量、投票數量、降序排序)
  • 創建問題,回答問題
  • 對問題投票,對答案投票
  • 對問題添加評論,對答案添加評論
  • 對問題進行修改,對答案進行修改
  • 我投過票的問題,我投過票的答案
  • 我瀏覽過的問題
  • 我回答的問題列表

API 實現概述

postman 文檔://documenter.getpostman.com/view/4874930/TVYM3F2M#4e7e4e11-c424-41ce-a463-3d1995a78ff8

api name
GET /api/question 查詢問題列表
GET /api/question/{id} 查詢單個問題
GET /api/question/{id}/answers 查詢單個問題帶答案
POST /api/question 創建問題
PATCH /api/question/{id} 修改問題
POST /api/question/{id}/answer 回答問題/添加答案
POST /api/question/{id}/up 向上投票問題
POST /api/question/{id}/down 向下投票問題
POST /api/question/{id}/comment 添加問題評論
GET /api/answer 查詢答案
POST /api/answer/{id}/up 向上投票答案
POST /api/answer/{id}/down 向下投票答案
PATCH /api/answer/{id} 修改答案
POST /api/answer/{id}/comment 添加答案評論

創建文檔類

  • question
  • answer
  • vote
  • comment
  • view
namespace LighterApi.Data.Question
{
    public class Question : Entity
    {
        public String ProjectId { get; set; }

        public string Title { get; set; }

        public string Content { get; set; }

        public List<string> Tags { get; set; } = new List<string>();

        public int ViewCount { get; set; }

        public int VoteCount { get; set; }

        public List<string> VoteUps { get; set; } = new List<string>();

        public List<string> VoteDowns { get; set; } = new List<string>();

        public List<string> Answers { get; set; } = new List<string>();

        public List<Comment> Comments { get; set; } = new List<Comment>();
    }
}
namespace LighterApi.Data.Question
{
    public class Answer : Entity
    {
        public string QuestionId { get; set; }

        public string Content { get; set; }

        public int VoteCount { get; set; }

        public List<string> VoteUps { get; set; } = new List<string>();

        public List<string> VoteDowns { get; set; } = new List<string>();

        public List<Comment> Comments { get; set; } = new List<Comment>();
    }
}
namespace LighterApi.Data.Question
{
    public class Vote : Entity
    {
        public string SourceType { get; set; }

        public string SourceId { get; set; }

        public EnumVoteDirection Direction { get; set; }
    }
}
namespace LighterApi.Data.Question
{
    public class Comment
    {
        public string Content { get; set; }

        public DateTime CreatedAt { get; set; }

        public string CreatedBy { get; set; }
    }
}
namespace LighterApi.Data.Question
{
    public class View : Entity
    {
        public string QuestionId { get; set; }
    }
}
namespace LighterApi.Share
{
    public class ConstVoteSourceType
    {
        public const string Question = "question";

        public const string Answer = "answer";
    }
}
namespace LighterApi.Share
{
    public enum EnumVoteDirection
    {
        Up = 1,
        Down = 0,
    }
}

集成 mongo db driven

  • 安裝 nuget 包
  • 服務注入 IMongoClient
  • 連接字元串

安裝 nuget 包

dotnet package install MongoDB.Driver

服務注入 IMongoClient

Startup

services.AddSingleton<IMongoClient>(sp =>
{
    return new MongoClient(Configuration.GetConnectionString("LighterMongoServer"));
});

appsettings.json

"LighterMongoServer": "mongodb://127.0.0.1"

連接字元串

連接到單個實例,默認127.0.0.1:27017
var client = new MongoClient();


指定一個連接字元串
var client = new MongoClient("mongodb://localhost:27017");


指寫帶密碼的連接字元串
var client = new MongoClient("mongodb://admin:password@localhost:27017");


連接到一個副本集,客戶端服務發現 
var client = new MongoClient("mongodb://localhost:27017,localhost:27018,localhost:27019"

GitHub源碼鏈接:

//github.com/MINGSON666/Personal-Learning-Library/tree/main/ArchitectTrainingCamp/LighterApi

知識共享許可協議

本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。

歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含鏈接: //www.cnblogs.com/MingsonZheng/ ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發布。

如有任何疑問,請與我聯繫 ([email protected]) 。