問題描述
想象下面的貓鼬模型:
const UserSchema = Schema({
//_id: ObjectId,
//more fields,
blockedIds: [{
type: ObjectId,
ref: 'User'
}]
})
獲取與某個 _id 的用戶的阻塞 ID 不匹配的所有用戶的最有效方法是什么?
What is the most efficient way to get all users that don't match the blockedIds of an user with a certain _id?
一種天真的方法是執行兩個查詢:
A naive way would be to to perform two queries:
User.findById(id).then(user => {
return User.find({_id: {$nin: user.blockedIds}})
})
是否可以使用聚合框架和 $facets 在一個查詢中完成?
Is it possible to use the aggregation framework and $facets to accomplish that in one query?
推薦答案
試試 non-correlated 來自 3.6 的子查詢,用于您的用例.
Try non-correlated sub query from 3.6 for your use case.
有點像
User.aggregate(
[{$lookup:{
from: "users",
pipeline:[
{$match: {_id:mongoose.Types.ObjectId(id)}},
{$project: {_id:0,blockedIds:1}}
],
as: "noncr"
}},
{$match:{
$expr:{
$not:[
{$in:[
$_id,
{$arrayElemAt:["$noncr.blockedIds",0]}
]}
]
}
}},
{$project:{noncr:0}}]
)
$lookup
為輸入 ID 拉入blockedIds",然后是 $match
過濾_id"不在blockedIds列表中的文檔.
$lookup
to pull in the "blockedIds" for input id followed by $match
to filter the documents where "_id" is not in list of blockedIds.
$expr
允許在 $match 階段使用聚合比較運算符.
$expr
allows use of aggregation comparison operators in $match stage.
$arrayElemAt
從 $lookup 數組中獲取第一個元素.
$arrayElemAt
to fetch the first element from $lookup array.
$in
將_id 與blockedIds 進行比較.
$in
to compare the _id against blockedIds.
$project
排除以從最終響應中刪除noncr"字段.
$project
with exclusion to remove the "noncr" field from the final response.
請注意,當您測試查詢時,在查找階段的from"屬性中使用集合名稱而不是模型或模式名稱.
Please note when you test query use the collection name not model or schema name in "from" attribute of look up stage.
這篇關于查詢依賴于 mongodb 中其他文檔值的文檔的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!