Day 17 Azure Cosmos DB API for MongoDB- 找个地方放资料

Azure Cosmos DB API for MongoDB- 找个地方放资料

MongoDB是一种NoSQL的资料库,用来处理半结构化资料的资料库系统,其储存的资料结构可以不需要事先定义,甚至可以自由新增栏位,不需要回头修改 schema ,可以自由定义资料结构(谜之声:这样真的是挺随便的啊......)。因为很自由,所以其实适用於一开始还在开发阶段,或者还在确认概念是否可行的阶段,这种时候通常资料结构都还不太确定。另一方面,也适用於资料之间没有复杂关联性的情况,或者服务比较注重资料的可用性和取得资料的速度。我想相对而言,在 Line chatbot 上要实作人脸登入,符合上述的情况,这的确只是一个小专案,资料结构可能随着不同的使用者,可以做不同的设计,且比起资料结构,我可能更在意 chatbot 能不能快速取得资料并且回应。

Azure Cosmos DB 是微软的全球分布式(globally distributed)多模型资料库服务,支援多种资料库,可用不同语法操作,而MongoDB也是其中一项服务。有时候,我们所设计的程序或服务,需要在全世界各个角落都能快速回应,且必须维持高度可用性,绝对不能断线,这时候 Azure Cosmos DB 全球分布的特性就能派上用场了。若要在多个 Azure 区域中部署自己的资料,可以在自己的帐户中新增 Azure 的服务区域,如此一来资料就能快速支援不同区域了。

这边 Azure Cosmos DB 提供的MongoDB服务,基本上可以想像成在 Azure 上建立MongoDB server,不同的是这个 MongoDB Server 的底层依旧是 Azure Cosmos DB,但所有操作都与一般MongoDB无异。

申请 Azure Cosmos DB API for MongoDB

  1. 进入https://portal.azure.com/#home
  2. 点选建立资源
  3. 搜寻并选择 Azure Cosmos DB API for MongoDB
  4. 名称和区域是必填项目,其他内容就是情况填写了。如果没有特别考量就直接依照预设条件设定。
  5. 可以考虑选择不同的容量模式:可以选择布建的输送量(provisioned throughput)和 serverless。差别就在於选择前者,可以让资料库无储存空间上限,也可以让资料库达到地理分散,延迟时间低於 10 毫秒;serverless 则完全没有上述优势,也只有 50 G 的储存空间。如果不想想这麽多,在试用期间,就直接选择预设值就好。
  6. 检阅 + 建立。

主要连接字串

主要连接字串其实就是连结MongoDB的 URI。

  • 到刚刚建立好的 Azure Cosmos DB。
  • 点选快速入门。
  • 在选择平台的地方,选择Python
  • 复制主要连接字串

'Python'套件

pip3.7 install pymongo

示范程序

这边不会完整教学MongoDB的用法,只会针对接下来会用到的部分做介绍。

  • 将人名与userId存入资料库
from pymongo import MongoClient
uri = "mongodb://mongoit:...."
client = MongoClient(uri, retryWrites=False)

# 取得名为 face_register 的资料库,若原本没有此资料库,此举也能产生此资料库
db = client['face_register']
# 取得名为 line 的 collection,若原本没有此 collection,此举也能产生此 collection
collect = db['line']
post = {"name": "Triathlon", "userId": "1234567890"}}
collect.insert_one(post)

特别一提的是,这边所使用的userId,是 Line 针对每个 chatbot 的每个使用者所做出来的 unique ID,所以同一个使用者在不同的 Line chatbot 之中,会有不同的userId,而且也跟在 Line App 上看到的 user ID 不同。我们可以利用 chatbot 取得 event 时,透过 event.source.user_id 取得 userId。将人名与userId存入资料库之後,下一篇文章提到的人脸登入,才可以进行身份比对。

  • 取得资料
collect.find_one({"name": "Triathlon"})

  • 纪录登入的时间
from datetime import datetime
collect_login = db["daily_login"]
now = datetime.now()
post = {"userId": "1234567890", "time": now.timestamp()}
collect_login.insert_one(post)
  • 检查一天之内是否有登入
yesterday = datetime.now() - timedelta(days=1)
# 检查符合条件的有多少笔:要符合User ID 且 timestamp 在一天之内的
result = collect_login.count_documents(
    {"$and": [{"userId": "1234567890"}, {"time": {"$gte": yesterday.timestamp()}}]}
)

这边需要用$and$gte来分别表示and>=,跟其他语法相比算是比较特别的地方。其它常用用法可参考:https://docs.mongodb.com/manual/reference/operator/query/


以上只是简单的示范,接下来就必须考虑有关人脸登入的几件事情:第一,需要用人脸和 Line user ID 做双重比对;第二,需要纪录登入时间;第三,需要确认最近一段时间内,是否曾经登入。下一篇,我们来试着实作人脸登入。


<<:  Day3 跟着官方文件学习Laravel-来一个登入画面

>>:  Day2 React是什麽呢?

D20 第十周 (回忆篇)

这礼拜在弄第九周作业,在 session 的部分花相对多的时间研究,主要是安全议题的关系。 然後也开...

Re: 新手让网页 act 起来: Day24 - React Hooks 之 useMemo

前言 昨天我们介绍过如何使用 React.memo 与 useCallback 来做效能优化,而 u...

Laravel 技术笔记 (二)【Controllers 控制器】

介绍 观看本篇前,建议先了解何谓 MVC 模式,简单说控制器的作用就像是交通警察,应用程序在接收 H...

Day 23:获取位置权限

本篇文章同步发表在 HKT 线上教室 部落格,线上影音教学课程已上架至 Udemy 和 Youtu...

Day 27:Blazor x Chart.js

Chart.js是一款open source的图表制作library,支援多种图表,包括Pie ch...