我是NoSQL的新手,所以在学习MongoDB的过程中,我决定制作一个帮助台应用程序。现在,设计数据模型,我有用户和票证,其建模如下。
User
----
|- mid (member id, String)
|- name (user name, String)
|- mail (e-mail, String)
\_ pass (md5 hashed password, String)
我试图通过引用来遵循这一点,票证将引用创建它们的用户以及正在回复票证的用户。我的结构如下:
Ticket
------
|- tid (ticket id, String)
|- title (title of ticket, String)
|- status (status of ticket, String)
|- replies (embedded replies doc, [{ mid: ..., msg: ... }])
|- assignee (whom the topic is assigned to, String, refers to users)
\_ priority (priority level of the ticket, 1-5, Number)
现在我想向用户显示所有未处理票证的列表;通过以下方式:
| Title | Num Replies | Assignee | Author | Priority |
|------------------------|-------------|----------|--------|----------|
| Unblock this URL | 5 | SHC | ABC | 5 |
| Install MS Office here | 2 | STC | XYZ | 4 |
...
我只是使用以下代码获取了所有打开的门票:
tickets.find({ "status": "open" }, (err, data) =>
{
if (err)
{
console.error(err);
res.json({
"success": false,
"message": "Failure to get from database"
});
}
else
{
// TODO: Convert the "mid" references in the data
}
});
到目前为止,这看起来很简单,但是这里的data
是一个开放票证数组,其中包含作者
和受让人
的字段作为成员 ID,我需要成员的姓名。
我当然可以进行另一个查询来查找成员(member)名称,但假设有 100 个开放票证,那么我会得到 201 个查询,这并不酷。
我确实尝试优化这个东西,并通过创建一个不同用户的数组,使用 $in
查询从数据库中获取用户对象,然后循环所有票证并使用得到的结果将它们映射到服务器中,从而只需 2 个查询。它有效,但我想知道如何正确地处理它,而不是使用任何 hack。
来自 MySQL 背景,我会在 MySQL 中的单个查询中完成此操作:
select t.tid, t.title, t.priority, a1.name, a2.name
from tickets t, users a1, users a2
where a1.mid = t.assignee and
a2.mid = t.author;
我应该如何使用 Mongoose 在 MongoDB 中处理这种查询?
最佳答案
您的 MySQL 查询使用联接 - 正如您所发现的,mongodb 不支持联接。
您有几个选项,您已经提供了其中一个。
creating an array of distinct users, fetching the user objects from the DB using the $in query and then looping over all the tickets and using the got results to map them in the server, making this to just 2 queries
...对我来说听起来不错。
第二,使用populate
- http://mongoosejs.com/docs/populate.html
您需要将您的ticket
架构更改为:
var ticketSchema = Schema({
assignee : { type: String, ref: 'User' },
title : String,
//etc...
});
然后,调用填充:
tickets.find({ "status": "open" })
.populate('assignee')
.exec(err, data) =>
{
if (err)
{
console.error(err);
res.json({
"success": false,
"message": "Failure to get from database"
});
}
else
{
// TODO: Convert the "mid" references in the data
}
});
请注意,在幕后,这实际上包装了多个查询 - 但不要 panic - 这是 NoSQL 的公认的权衡。
如果您的“hacky”方式有效,我建议坚持使用 - 这并不是真正的 hack,只是缺乏 JOIN 的解决方法。
关于javascript - Mongoose - 从多个集合中查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44117002/