2020-05-01

MongoDB Collections 之間的關聯性

MongoDB Collections 之間的關聯性

MongoDB 官方關於關聯性的說明,在關聯式資料庫中,表和表之間的關聯是很平常的事情,在 MongoDB 為了方便資料的維護,當然也有易於處理關聯的設計。在此就不談一對一的情況。

官方 以文件參照建構一對多的模型 裡面的例子其實很容易了解,我們就以裡面的範例來討論。

以下是直接使用嵌入子文件的方式來處理 books 中的出版商資料,很明顯的在維護上每次要更動的資料量會很多:

{ title: "MongoDB: The Definitive Guide", author: ["Kristina Chodorow", "Mike Dirolf"], published_date: ISODate("2010-09-24"), pages: 216, language: "English", publisher: { name: "O'Reilly Media", founded: 1980, location: "CA" } } { title: "50 Tips and Tricks for MongoDB Developer", author: "Kristina Chodorow", published_date: ISODate("2011-05-06"), pages: 68, language: "English", publisher: { name: "O'Reilly Media", founded: 1980, location: "CA" } }

另一種是將出版商出版的書籍記錄在出版商的 collection publishers 內。缺點是,若要從書籍去找出版商,這樣子的效能會比較差:

{ name: "O'Reilly Media", founded: 1980, location: "CA", books: [123456789, 234567890, ...] } { _id: 123456789, title: "MongoDB: The Definitive Guide", author: ["Kristina Chodorow", "Mike Dirolf"], published_date: ISODate("2010-09-24"), pages: 216, language: "English" } { _id: 234567890, title: "50 Tips and Tricks for MongoDB Developer", author: "Kristina Chodorow", published_date: ISODate("2011-05-06"), pages: 68, language: "English" }

比較好的做法,就是 books 的 publisher_id 關聯到 publishers 的 _id。

db.publishers.insertOne({ _id: "oreilly", name: "O'Reilly Media", founded: 1980, location: "CA" }) db.books.insertMany([{ _id: 123456789, title: "MongoDB: The Definitive Guide", author: ["Kristina Chodorow", "Mike Dirolf"], published_date: ISODate("2010-09-24"), pages: 216, language: "English", publisher_id: "oreilly" }, { _id: 234567890, title: "50 Tips and Tricks for MongoDB Developer", author: "Kristina Chodorow", published_date: ISODate("2011-05-06"), pages: 68, language: "English", publisher_id: "oreilly" }])

查詢時,使用 aggregate() 和 $lookup$lookup 可以提供同關聯資料庫的 JOIN,方式如下:

db.books.aggregate([ { $lookup: { from: 'publishers', foreignField: '_id', localField: 'publisher_id', as: 'publisher' } } ]).pretty()
  • from: 為要合併查詢的 collection (publishers)。
  • foreignField: 為 publishers 的對應欄位。
  • localField: 為 books 中對應 publishers._id 的欄位。
  • as: 為查詢結果將 publishers 的文件所放入的欄位(暫時,查詢呈現)。

沒有留言:

FB 留言