iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Software Development

NoSQL: Not Only SQL系列 第 22

[Day 22] Document Database: 以 MongoDB 為例

  • 分享至 

  • xImage
  •  

這次一樣使用 .NET6 WebAPI 專案搭配 NuGet 套件進行開發,MongoDB 也有提供官方的 NuGet 套件 MongoDB.Driver方便開發者使用,裡面提供的相關方法簽章跟前一篇所使用的 mongosh 很接近,使用起來滿簡便的也很完整,像是同個操作都會提供同步和非同步兩種方法可以選擇。

基本設定

建立 WebAPI 專案,版本為 .NET6,命名為 IronmanMongoDbDemo。
https://ithelp.ithome.com.tw/upload/images/20220924/20151137o9GcZhzJo3.png

專案加入對 MongoDB.Driver NuGet 套件的參考。
https://ithelp.ithome.com.tw/upload/images/20220924/20151137BuaIafO99L.png

把接下來會需要用到的常數都先放在 Consts.cs 中。

因為是練習想節省相關設定,所以直接把 ConnectionString 包含帳號密碼寫在程式碼中,但這不是個安全的作法,正式開發時不建議這樣設定。

public static class Consts
{
    public static string ConnectionString = "mongodb://appUser:appPwd@localhost:1235";
    public static string DbName = "demodb";
    public static string CollectionName = "NotificationSettings";
}

Program.cs 中注入 MongoClient 並設定 ConnectionString,接著注入 IMongoDatabase

// Add services to the container.
builder.Services.AddSingleton(new MongoClient(Consts.ConnectionString));
builder.Services.AddSingleton(sp =>
{
    var client = sp.GetRequiredService<MongoClient>();
    return client.GetDatabase(Consts.DbName);
});

建立這次要使用的 DataEntity,命名為 UserSettingDataEntity,並透過設定 [BsonId] Attribute 指定 UserId 為這個資料的 Id。

public class UserSettingDataEntity
{
    [BsonId]
    public string UserId { get; set; }
    
    public string Address { get; set; }
    
    public bool NeedNotify { get; set; }
}

建立 NotificationSettingsController.cs ,在建構子取得剛剛注入的 IMongoDatabase,並透過 CollectionName 取得存放 UserSettingDataEntity 的 Collection。

[ApiController]
[Route("[Controller]/[Action]")]
public class NotificationSettingsController : ControllerBase
{
    private readonly IMongoCollection<UserSettingDataEntity> _notificationSettingsCollection;

    public NotificationSettingsController(IMongoDatabase db)
    {
        _notificationSettingsCollection = db.GetCollection<UserSettingDataEntity>(Consts.CollectionName);
    }
}

建立 API Endpoint 及其功能

接下來就可以建立各功能的 endpoint 及功能了,包含:

  • 建立通知設定
  • 修改通知設定
  • 以 UserId 查詢設定
  • 以 UserId 刪除設定

首先新增建立通知設定的 endpoint,透過呼叫 collection.InsertOneAsync(DataEntity) 新增一筆 Document 進資料庫。

    [HttpPost]
    public async Task<IActionResult> InsertSetting([FromBody] UpsertRequest requestPayload)
    {
        var dbEntity = requestPayload.ToDataEntity();
        await _notificationSettingsCollection.InsertOneAsync(dbEntity);
        return NoContent();
    }

其中 RequestPayload 如下:

public class UpsertRequest
{
    public string UserId { get; set; }
    
    public string Address { get; set; }
    
    public bool NeedNotify { get; set; }

    public UserSettingDataEntity ToDataEntity()
    {
        return new UserSettingDataEntity
        {
            UserId = UserId,
            Address = Address,
            NeedNotify = NeedNotify
        };
    }
}

接著是取得資料,使用 collection.FindAsync(過濾條件) 會回傳可以取得符合該條件資料的 Cursor,再透過 Cursor 取得資料,而過濾條件可以直接使用 C# 的 Lambda expressions。

    [HttpGet]
    public async Task<IActionResult> GetSetting(string userId)
    {
        var cursor = await _notificationSettingsCollection.FindAsync(x => x.UserId == userId);
        var result = await cursor.FirstOrDefaultAsync();
        if (result is null)
        {
            return NotFound();
        }
        return Ok(result);
    }

再來是修改,使用 collection.ReplaceOneAsync(過濾條件, DataEntity) 可以透過指定條件的方式把整個 Document 覆蓋掉,這邊使用指定 Id 的方式來實現。

    [HttpPut]
    public async Task<IActionResult> UpdateSetting([FromBody] UpsertRequest requestPayload)
    {
        var dbEntity = requestPayload.ToDataEntity();
        var result = await _notificationSettingsCollection.ReplaceOneAsync(x => x.UserId == requestPayload.UserId, dbEntity);
        return Ok(result);
    }

最後是刪除設定的部分,使用 collection.DeleteOneAsync(過濾條件) 也是透過指定條件的方式刪除資料。

    [HttpDelete]
    public async Task<IActionResult> DeleteSetting(string userId)
    {
        var result = await _notificationSettingsCollection.DeleteOneAsync(x => x.UserId == userId);
        return Ok(result);
    }

這樣基本的 API 就開發完成了!
https://ithelp.ithome.com.tw/upload/images/20220924/201511372u8csvkUuE.png


上一篇
[Day 21] Document Database: 以 MongoDB 為例
下一篇
[Day 23] Column Family Database:簡介
系列文
NoSQL: Not Only SQL30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言