繁体   English   中英

猫鼬-从多个集合中查询

[英]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是一个开放的票证数组, authorassignee的字段作为成员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

http://mongoosejs.com/docs/populate.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM