[英]Mongoose - Query from multiple collections
我是NoSQL的新手,因此在通过MongoDB学习它的过程中,我决定制作一个Help Desk应用程序。 现在,在设计数据模型时,我具有如下的用户和票证。
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
是一个开放的票证数组, author
和assignee
的字段作为成员ID,我需要成员的姓名。
我当然可以再执行一次查询以查找成员名称,但是假设有100张未公开的票证,那么我将获得201条查询,这并不酷。
我确实尝试优化了这一点,并通过创建一组不同的用户来解决,使用$in
查询从数据库中获取用户对象,然后遍历所有票证,并使用获得的结果将它们映射到服务器中,使其仅涉及2个查询。 它可以工作,但是我想知道如何正确地解决它,而不要遇到任何黑客。
从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;
我应该如何在MongoDB中使用Mongoose处理这种查询?
您的MySQL查询使用了一个连接-您发现mongodb不支持该连接。
您有两个选择,您已经提供了其中一个。
创建一组不同的用户,使用$ in查询从数据库中获取用户对象,然后遍历所有票证,并使用get结果将它们映射到服务器中,从而仅进行2个查询
...对我来说并不坏。
其次,使用populate
: //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
}
});
请注意,实际上,这实际上是包装了多个查询-但是请不要担心-这是NoSQL可接受的折衷方案。
如果您的“ hacky”方式有效,我建议您坚持使用-这并不是真正的hack,只是缺少JOIN的一种解决方法。
您正在寻找populate(...)
方法,该方法允许您插入后面的相关对象(用户),而不是mid
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.