在Apollo GraphQL解析器中使用的父級參數與MongoDB聚合中的$lookup階段用於連接Mongoose模型的比較
P粉543344381
2023-09-02 09:22:26
<p>我正在使用 Apollo GraphQL 和 Mongoose 開發後端應用程式。我有兩個模型:User 和 Post,它們具有一對多關係(一個用戶可以有多個帖子,但一個帖子屬於一個用戶)。 </p>
<p>我想查詢 GraphQL 架構中的用戶字段,以按用戶 ID 獲取用戶以及屬於該用戶的所有帖子。我還想查詢我的帖子類型中的作者字段以獲取撰寫該帖子的用戶。 </p>
<p>我了解到,有兩種方法可以連接 MongoDB 中不同集合的資料:使用 Apollo GraphQL 解析器中的父參數,或使用 MongoDB 聚合中的 $lookup 階段。 </p>
<p>父參數是一個對象,其中包含從父字段上的解析器返回的結果。父參數可用於存取父欄位或類型中的數據,並將其傳遞給子欄位或類型。例如,我可以使用它來加入貓鼬模型,如下所示:</p>
<pre class="brush:php;toolbar:false;">type User {
id: ID!
name: String
posts: [Post]
}
type Post {
id: ID!
title: String
author: User
}
type Query {
user(id: ID!): User
}
const resolvers = {
User: {
posts(parent, args, context) {
return context.db.Post.find({ author: parent.id });
},
},
};</pre>
<p>$lookup 階段是一個聚合管道階段,它對同一資料庫中的另一個集合執行左外連接。 $lookup 階段可用於將多個集合中的資料合併到單一結果集中。例如,我可以用它來加入這樣的模型:</p>
<pre class="brush:php;toolbar:false;">db.posts
.aggregate([
{
$lookup: {
from: "users",
localField: "author",
foreignField: "_id",
as: "author",
},
},
])
.toArray((err, posts) => {
console.log(posts);
});</pre>
<p>我不確定我的應用程式應該使用哪一個。我想選擇更有效率、可擴展和可維護的選項。 </p>
<p>在 Apollo GraphQL 解析器中使用父參數和在 MongoDB 聚合中使用 $lookup 階段來加入 Mongoose 模型之間的主要差異和權衡是什麼? </p>
我推薦第一種技術 - 它肯定更乾淨並且可能更快。您應該確保為
author
欄位建立索引 - 就像在 RDB 中為外鍵建立索引一樣。這兩種方法之間確實存在一些差異
使用解析器
我發現這種方法更直觀、更具可讀性,因此更易於維護,尤其是對於複雜的查詢
但是,在處理大量資料時,它可能不是最有效的,因為它會為每個巢狀欄位對資料庫進行額外的呼叫。在處理大量複雜的巢狀查詢時,這可能會成為效能瓶頸。
使用$lookup
另一方面,$lookup 操作通常效能較高,因為它們使用單一資料庫呼叫來連接和檢索資料。
但是,隨著查詢複雜性的增加,$lookup 操作可能會變得複雜且難以閱讀和維護。它可能需要更多關於 MongoDB 查詢語言的知識,並且可能不像解析器方法那樣簡單易用。寫得不好的聚合可能會導致效能問題,所以要絕對確定你在做什麼。
因此,在您的範例中,我不介意使用解析器方法,即使使用聚合速度更快,第一種方法也會更容易閱讀/改進/維護。
希望有幫助:)