搜尋
首頁科技週邊IT業界在MongoDB NOSQL數據庫中使用加入

Using JOINs in MongoDB NoSQL Databases

核心要點

  • MongoDB,一個NoSQL數據庫,在3.2版本中引入了新的$lookup操作符,可以在兩個或多個集合上執行類似LEFT-OUTER-JOIN的操作,從而實現類似關係型數據庫的數據管理。然而,此操作符僅限於聚合操作中使用,聚合操作比簡單的查找查詢更複雜,通常也更慢。
  • MongoDB的$lookup操作符需要四個參數:localField(輸入文檔中的查找字段)、from(要連接的集合)、foreignField(在from集合中查找的字段)和as(輸出字段的名稱)。此操作符可用於聚合查詢中,以匹配帖子、按順序排序、限制項目數量、連接用戶數據、展平用戶數組並僅返回必要的字段。
  • 雖然MongoDB的$lookup操作符很有用,可以幫助在NoSQL數據庫中管理少量關係數據,但它不能替代SQL中更強大的JOIN子句。如果在MongoDB中刪除用戶文檔,孤兒帖子文檔將保留,表明缺乏約束。因此,如果頻繁使用$lookup操作符,可能表明使用了錯誤的數據存儲,關係型(SQL)數據庫可能更適合。

Using JOINs in MongoDB NoSQL Databases 感謝Julian Motz的同行評審幫助。


SQL和NoSQL數據庫之間最大的區別之一是JOIN。在關係型數據庫中,SQL JOIN子句允許您使用它們之間的一個公共字段來組合來自兩個或多個表的行。例如,如果您有書籍和出版商的表,您可以編寫如下SQL命令:

SELECT book.title, publisher.name
FROM book
LEFT JOIN book.publisher_id ON publisher.id;

換句話說,book表有一個publisher_id字段,它引用publisher表中的id字段。

這是實用的,因為單個出版商可以提供數千本書籍。如果我們將來需要更新出版商的詳細信息,我們可以更改單個記錄。數據冗餘被最小化,因為我們不需要為每一本書重複出版商的信息。此技術稱為規範化。

SQL數據庫提供一系列規範化和約束功能,以確保維護關係。

NoSQL == No JOIN?

並非總是如此…

面向文檔的數據庫(如MongoDB)旨在存儲非規範化數據。理想情況下,集合之間不應該有任何關係。如果相同的數據需要在兩個或多個文檔中,則必須重複。

這可能會令人沮喪,因為幾乎沒有你永遠不需要關係數據的情況。幸運的是,MongoDB 3.2引入了一個新的$lookup操作符,它可以在兩個或多個集合上執行類似LEFT-OUTER-JOIN的操作。但是有一個問題…

MongoDB聚合

$lookup僅允許在聚合操作中使用。可以將其視為一系列操作符的管道,這些操作符查詢、過濾和分組結果。一個操作符的輸出用作下一個操作符的輸入。

聚合比簡單的查找查詢更難理解,並且通常運行速度較慢。但是,它們功能強大,對於復雜的搜索操作來說是一個寶貴的選項。

最好用一個例子來解釋聚合。假設我們正在創建一個具有用戶集合的社交媒體平台。它將每個用戶的詳細信息存儲在單獨的文檔中。例如:

SELECT book.title, publisher.name
FROM book
LEFT JOIN book.publisher_id ON publisher.id;

我們可以根據需要添加任意數量的字段,但是所有MongoDB文檔都需要一個具有唯一值的_id字段。 _id類似於SQL主鍵,如果需要,將自動插入。

我們的社交網絡現在需要一個帖子集合,該集合存儲用戶的大量有見地的更新。文檔存儲文本、日期、評級和在user_id字段中引用撰寫它的用戶:

{
  "_id": ObjectID("45b83bda421238c76f5c1969"),
  "name": "User One",
  "email": "userone@email.com",
  "country": "UK",
  "dob": ISODate("1999-09-13T00:00:00.000Z")
}

我們現在想顯示所有用戶按時間逆序排列的最後二十個評級為“important”的帖子。每個返回的文檔都應包含文本、帖子的時間以及關聯用戶的姓名和國家/地區。

MongoDB聚合查詢傳遞一個管道操作符數組,這些操作符按順序定義每個操作。首先,我們需要使用$match過濾器從帖子集合中提取所有具有正確評級的文檔:

{
  "_id": ObjectID("17c9812acff9ac0bba018cc1"),
  "user_id": ObjectID("45b83bda421238c76f5c1969"),
  "date": ISODate("2016-09-05T03:05:00.123Z"),
  "text": "My life story so far",
  "rating": "important"
}

我們現在必須使用$sort操作符按時間逆序對匹配的項目進行排序:

{ "$match": { "rating": "important" } }

由於我們只需要二十個帖子,因此我們可以應用$limit階段,以便MongoDB只需要處理我們想要的數據:

{ "$sort": { "date": -1 } }

我們現在可以使用新的$lookup操作符連接來自用戶集合的數據。它需要一個具有四個參數的對象:

  • localField:輸入文檔中的查找字段
  • from:要連接的集合
  • foreignField:在from集合中查找的字段
  • as:輸出字段的名稱。

因此,我們的操作符是:

{ "$limit": 20 }

這將在我們的輸出中創建一個名為userinfo的新字段。它包含一個數組,其中每個值都與用戶文檔匹配:

{ "$lookup": {
  "localField": "user_id",
  "from": "user",
  "foreignField": "_id",
  "as": "userinfo"
} }

我們之間存在一對一的關係post.user_iduser._id,因為一個帖子只能有一個作者。因此,我們的userinfo數組將永遠只包含一個項目。我們可以使用$unwind操作符將其分解成一個子文檔:

"userinfo": [
  { "name": "User One", ... }
]

輸出現在將轉換為更實用的格式,可以應用其他操作符:

{ "$unwind": "$userinfo" }

最後,我們可以使用管道中的$project階段返回文本、帖子的時間、用戶的姓名和國家/地區:

SELECT book.title, publisher.name
FROM book
LEFT JOIN book.publisher_id ON publisher.id;

將所有內容放在一起

我們的最終聚合查詢匹配帖子、按順序排序、限制為最新的二十個項目、連接用戶數據、展平用戶數組並僅返回必要的字段。完整命令:

{
  "_id": ObjectID("45b83bda421238c76f5c1969"),
  "name": "User One",
  "email": "userone@email.com",
  "country": "UK",
  "dob": ISODate("1999-09-13T00:00:00.000Z")
}

結果是一個最多包含二十個文檔的集合。例如:

{
  "_id": ObjectID("17c9812acff9ac0bba018cc1"),
  "user_id": ObjectID("45b83bda421238c76f5c1969"),
  "date": ISODate("2016-09-05T03:05:00.123Z"),
  "text": "My life story so far",
  "rating": "important"
}

太棒了!我終於可以切換到NoSQL了!

MongoDB $lookup很有用且功能強大,但即使這個基本示例也需要一個複雜的聚合查詢。它不能替代SQL中更強大的JOIN子句。 MongoDB也不提供約束;如果刪除用戶文檔,孤兒帖子文檔將保留。

理想情況下,$lookup操作符應該很少需要。如果您經常需要它,您可能使用了錯誤的數據存儲……

如果您有關係數據,請使用關係型(SQL)數據庫!

也就是說,$lookup是MongoDB 3.2的一個受歡迎的補充。它可以克服在NoSQL數據庫中使用少量關係數據時的一些更令人沮喪的問題。

關於在MongoDB NoSQL數據庫中使用JOIN的常見問題解答 (FAQ)

SQL連接和MongoDB連接有什麼區別?

在SQL數據庫中,連接操作根據它們之間相關的列組合來自兩個或多個表的行。但是,MongoDB作為NoSQL數據庫,不支持傳統的SQL連接。相反,MongoDB提供兩種執行類似操作的方法:聚合中的$lookup階段和$graphLookup階段。這些方法允許您將來自多個集合的數據組合到單個結果集中。

MongoDB中的$lookup階段是如何工作的?

MongoDB中的$lookup階段允許您連接來自另一個集合(“已連接”集合)的文檔,並將已連接的文檔添加到輸入文檔中。 $lookup階段指定“from”集合、“localField”和“foreignField”用於匹配文檔,以及“as”字段用於輸出文檔。它類似於SQL中的左外連接,返回來自輸入集合的所有文檔以及來自“from”集合的匹配文檔。

我可以使用MongoDB連接執行遞歸搜索嗎?

是的,MongoDB為遞歸搜索提供了$graphLookup階段。 $graphLookup階段對指定的集合執行遞歸搜索,並可以選擇限制搜索的深度和廣度。它對於查詢分層數據或圖很有用,其中級別數未知或可能變化。

如何在使用MongoDB連接時優化性能?

為了在使用MongoDB連接時優化性能,請考慮以下策略:對“localField”和“foreignField”使用索引以加快匹配過程;限制“from”集合中的文檔數量;以及在$lookup階段之前使用$match$project階段來過濾和轉換文檔。

我可以在MongoDB中連接多個集合嗎?

是的,您可以通過在聚合管道中鏈接多個$lookup階段來連接多個MongoDB集合。每個$lookup階段都會將來自另一個集合的已連接文檔添加到輸入文檔中。

在使用MongoDB連接時,如何處理空值或缺失值?

在使用MongoDB連接時,如果輸入集合中的文檔與“from”集合中的任何文檔都不匹配,則$lookup階段會向“as”字段添加一個空數組。您可以通過在$lookup階段之後添加$match階段來處理這些空值或缺失值,以過濾掉具有空“as”字段的文檔。

我可以將MongoDB連接與分片集合一起使用嗎?

從MongoDB 3.6開始,$lookup$graphLookup階段可以接受分片集合作為“from”集合。但是,由於額外的網絡開銷,性能可能不如非分片集合。

如何對MongoDB中的已連接文檔進行排序?

您可以通過在聚合管道中的$lookup階段之後添加$sort階段來對MongoDB中的已連接文檔進行排序。 $sort階段按升序或降序對指定字段中的文檔進行排序。

我可以將MongoDB連接與find()方法一起使用嗎?

不可以,MongoDB連接不能與find()方法一起使用。 $lookup$graphLookup階段是聚合框架的一部分,它提供比find()方法更高級的數據處理功能。

如何調試或排除MongoDB連接故障?

要調試或排除MongoDB連接故障,您可以使用explain()方法來分析聚合管道的執行計劃。 explain()方法提供有關階段的詳細信息,包括處理的文檔數量、花費的時間以及索引的使用情況。

以上是在MongoDB NOSQL數據庫中使用加入的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
定制電信軟件的好處定制電信軟件的好處May 11, 2025 am 08:28 AM

定制电信软件开发无疑是一项相当大的投资。然而,从长远来看,您可能会意识到,这样的项目可能更具成本效益,因为它可以像市场上任何现成的解决方案一样提高您的生产力。了解构建定制电信系统的最重要优势。 获取您所需的确切功能 您可以购买的现成电信软件有两个潜在问题。有些缺乏可能显著改善您工作效率的有用功能。有时您可以通过一些外部集成来增强它们,但这并不总是足以使它们变得出色。 其他软件功能过多,使用起来过于复杂。您可能不会使用其中的一些(永远不会!)。大量的功能通常还会增加价格。 基于您的需求

CNCF觸發了ARM64和X86的平台平等突破CNCF觸發了ARM64和X86的平台平等突破May 11, 2025 am 08:27 AM

Arm64 架構開源軟件的 CI/CD 難題與解決方案 在 Arm64 架構上部署開源軟件需要一個強大的 CI/CD 環境。然而,Arm64 和傳統 x86 處理器架構的支持水平之間存在差異,Arm64 通常處於劣勢。面向多種架構的基礎設施組件開發人員對工作環境有一定的期望: 一致性:跨平台使用的工具和方法保持一致,避免因採用不太流行的平台而需要改變開發流程。 性能:平台和支持機制具有良好的性能,確保在支持多個平台時部署方案不會因速度不足而受影響。 測試覆蓋率:對所有平台同時進行效率、合規性和

21個開發人員新聞通訊將在2025年訂閱21個開發人員新聞通訊將在2025年訂閱Apr 24, 2025 am 08:28 AM

與這些頂級開發人員新聞通訊有關最新技術趨勢的了解! 這個精選的清單為每個人提供了一些東西,從AI愛好者到經驗豐富的後端和前端開發人員。 選擇您的收藏夾並節省時間搜索REL

使用AWS ECS和LAMBDA的無服務器圖像處理管道使用AWS ECS和LAMBDA的無服務器圖像處理管道Apr 18, 2025 am 08:28 AM

該教程通過使用AWS服務來指導您通過構建無服務器圖像處理管道。 我們將創建一個部署在ECS Fargate群集上的next.js前端,與API網關,Lambda函數,S3桶和DynamoDB進行交互。 Th

CNCF ARM64飛行員:影響和見解CNCF ARM64飛行員:影響和見解Apr 15, 2025 am 08:27 AM

該試點程序是CNCF(雲本機計算基礎),安培計算,Equinix金屬和驅動的合作,簡化了CNCF GitHub項目的ARM64 CI/CD。 該計劃解決了安全問題和績效

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器