搜尋
首頁科技週邊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
使用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。 該計劃解決了安全問題和績效

使用GO構建網絡漏洞掃描儀使用GO構建網絡漏洞掃描儀Apr 01, 2025 am 08:27 AM

此基於GO的網絡漏洞掃描儀有效地確定了潛在的安全弱點。 它利用了GO的並發功能的速度功能,包括服務檢測和漏洞匹配。讓我們探索它的能力和道德

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

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

熱工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器