javascript - Mongoose - 从多个集合中查询

标签 javascript node.js mongodb mongoose

我是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/

相关文章:

javascript - Zombie.js 和写入窗口的脚本

javascript - 使用年、月、日、小时、秒格式每分钟刷新图像

javascript - 如何设置不可更改的页面大小

mongodb - docker备份和恢复mongodb

javascript - MongoDB 集群中的 IP 白名单 Firebase 云函数

java - 如何使用 Java 从 MongoDB 3.4 版本获取数据?

使用 jQuery 的 javascript 关联数组长度

Javascript 内存泄漏 - Canvas HTML5 jQuery

node.js - 无法使用 Google Cloud 的 Oauth2 发送 NodeMailer(响应代码 : 530)

Node.js 堆栈跟踪信息