我有 3 個模型:
- 學習
- 詞集
- 類別
Study model 參考到 WordSet,然后 WordSet 參考到 Category。
據我所知,對于通常的顯示資料,我使用填充。但在這種情況下,我需要一個包含 many 的查詢$lookup。
如何從 WordSet 中“填充”類別并僅顯示重復次數最多的類別?
我會得到這樣的回應:
"stats": [
{
"_id": null,
"numberOfStudies": 4,
"averageStudyTime": 82.5,
"allStudyTime": 330,
"longestStudy": 120,
"allLearnedWords": 8
"hardestCategory": "Work" // only this field is missing
}
]
我試過這樣做:
const stats = await Study.aggregate([
{
// join User table
$lookup: {
from: 'User',
let: { userId: '$user' },
pipeline: [
{
$match: { $expr: { $eq: ['$_id', '$$userId'] } },
},
],
as: 'currentUser',
},
},
{
// join WordSet table
$lookup: {
from: 'WordSet',
let: { wordSetId: '$learnedWordSet' },
pipeline: [
{
$match: { $expr: { $eq: ['$_id', '$$wordSetId'] } },
},
{
// from this moment i'm not sure how to make it work
$lookup: {
from: 'Category',
let: { categoryId: '$category' },
pipeline: [
{
$match: { $expr: { $in: ['$_id', '$$categoryId'] } },
},
],
as: 'category',
},
},
],
as: 'wordSet',
},
},
{ // add wordset with category? this is not working
$addFields: {
wordSet: {
$arrayElemAt: ['$wordSet', 0],
},
},
},
{ // search by logged user
$match: { user: new ObjectID(currentUserId) },
},
{
$group: {
// display statistics about user's studying
_id: null,
numberOfStudies: { $sum: 1 },
averageStudyTime: { $avg: '$studyTime' },
allStudyTime: { $sum: '$studyTime' },
longestStudy: { $max: '$studyTime' },
allLearnedWords: { $sum: { $size: '$learnedWords' } },
// category: check which category is repeated the most and display it
},
},
]);
學習
const studySchema = new mongoose.Schema({
name: {
type: String,
},
studyTime: {
type: Number,
},
learnedWords: [String],
notLearnedWords: [String],
learnedWordSet: {
type: mongoose.Schema.Types.ObjectId,
ref: 'WordSet',
},
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
});
詞集
const wordSetSchema = new mongoose.Schema({
name: {
type: String,
},
category: {
type: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Category',
required: true,
},
],
},
});
類別
const categorySchema = new mongoose.Schema({
name: {
type: String,
},
});
uj5u.com熱心網友回復:
我不確定我是否理解正確,您可以嘗試查詢,我已經改進了階段的使用,
$match總是嘗試在第一階段使用 stage
$lookup使用 User 集合,不需要管道版本,可以使用 localField 和 foreignField 屬性我不認為有任何用戶檔案和查找階段的用途,因為您只需要最后一個
$group階段的統計資料。所以你可以跳過這個查找階段
- 在 WordSet 查找中,
$match你的情況$project顯示必填欄位$unwind解構category陣列$group通過category并獲得總計數$sort按count降序排列$limit僅獲取最常用的第一個和單個元素$llokup有Category收藏$project要顯示必填欄位,請獲取第一個類別名稱
$groupstage,hardestCategory獲取$first類別名稱
const stats = await Study.aggregate([
{ $match: { user: new ObjectID(currentUserId) } },
{
$lookup: {
from: "User",
localField: "user",
foreignField: "_id",
as: "currentUser"
}
},
{
$lookup: {
from: "WordSet",
let: { wordSetId: "$learnedWordSet" },
pipeline: [
{ $match: { $expr: { $eq: ["$_id", "$$wordSetId"] } } },
{
$project: {
_id: 0,
category: 1
}
},
{ $unwind: "$category" },
{
$group: {
_id: "$category",
count: { $sum: 1 }
}
},
{ $sort: { count: -1 } },
{ $limit: 1 },
{
$lookup: {
from: "Category",
localField: "_id",
foreignField: "_id",
as: "category"
}
},
{
$project: {
_id: 0,
category: { $arrayElemAt: ["$category.name", 0] }
}
}
],
as: "wordSet"
}
},
{
$group: {
_id: null,
numberOfStudies: { $sum: 1 },
averageStudyTime: { $avg: "$studyTime" },
allStudyTime: { $sum: "$studyTime" },
longestStudy: { $max: "$studyTime" },
allLearnedWords: {
$sum: { $size: "$learnedWords" }
},
hardestCategory: {
$first: {
$first: "$wordSet.category"
}
}
}
}
])
操場
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/401460.html
