-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnested-populate.example.js
More file actions
145 lines (127 loc) · 3.47 KB
/
nested-populate.example.js
File metadata and controls
145 lines (127 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* 深度 Populate 使用示例
*
* 场景:博客系统
* - User 有多个 Post
* - Post 有多个 Comment
* - Comment 有一个 Author (User)
*/
const MonSQLize = require('monsqlize');
const { Model } = MonSQLize;
// 1. 定义 Model
Model.define('users', {
schema: (dsl) => dsl({
username: 'string!',
email: 'string!'
}),
relations: {
posts: {
from: 'posts',
localField: '_id',
foreignField: 'authorId',
single: false
}
}
});
Model.define('posts', {
schema: (dsl) => dsl({
title: 'string!',
content: 'string!',
authorId: 'objectId'
}),
relations: {
author: {
from: 'users',
localField: 'authorId',
foreignField: '_id',
single: true
},
comments: {
from: 'comments',
localField: '_id',
foreignField: 'postId',
single: false
}
}
});
Model.define('comments', {
schema: (dsl) => dsl({
content: 'string!',
postId: 'objectId',
authorId: 'objectId'
}),
relations: {
author: {
from: 'users',
localField: 'authorId',
foreignField: '_id',
single: true
}
}
});
// 2. 连接数据库
const msq = new MonSQLize({
type: 'mongodb',
databaseName: 'blog',
config: { uri: 'mongodb://localhost:27017' }
});
async function examples() {
await msq.connect();
const User = msq.model('users');
// ========== 示例 1:基本嵌套 populate ==========
console.log('\n示例 1:User -> Posts -> Comments');
const user1 = await User.findOne({ username: 'john' })
.populate({
path: 'posts',
populate: 'comments' // 嵌套填充评论
});
console.log('用户:', user1.username);
console.log('文章数:', user1.posts.length);
console.log('第一篇文章的评论数:', user1.posts[0]?.comments?.length || 0);
// ========== 示例 2:3 层嵌套 ==========
console.log('\n示例 2:User -> Posts -> Comments -> Comment Author');
const user2 = await User.findOne({ username: 'john' })
.populate({
path: 'posts',
populate: {
path: 'comments',
populate: 'author' // 评论的作者(第 3 层)
}
});
const firstComment = user2.posts[0]?.comments[0];
if (firstComment) {
console.log('评论内容:', firstComment.content);
console.log('评论作者:', firstComment.author?.username);
}
// ========== 示例 3:带选项的嵌套 populate ==========
console.log('\n示例 3:嵌套 populate + 选项');
const user3 = await User.findOne({ username: 'john' })
.populate({
path: 'posts',
select: 'title', // 只选择标题
populate: {
path: 'comments',
select: 'content', // 只选择评论内容
sort: { createdAt: -1 }, // 按时间倒序
limit: 5 // 最多 5 条评论
}
});
console.log('文章(仅标题):', user3.posts.map(p => p.title));
console.log('最新 5 条评论:', user3.posts[0]?.comments.length);
// ========== 示例 4:混合链式和嵌套 ==========
console.log('\n示例 4:混合使用');
const user4 = await User.findOne({ username: 'john' })
.populate('profile') // 链式:填充用户资料
.populate({
path: 'posts',
populate: 'comments' // 嵌套:填充文章评论
});
console.log('用户资料:', user4.profile);
console.log('文章和评论:', user4.posts[0]?.comments);
await msq.close();
}
// 运行示例
if (require.main === module) {
examples().catch(console.error);
}
module.exports = { examples };