【问题标题】:Retrieve document plus sub-documents with Mongoose/MongoDB使用 Mongoose/MongoDB 检索文档和子文档
【发布时间】:2015-05-25 08:46:53
【问题描述】:

MongoDB/Mongoose 的 Express.js 新手,我不知道如何查询它并获取我需要的 JSON。

我有一份乐器清单。有些乐器是一种子类型,所以我将它们与一种乐器联系起来。所以,我有一个看起来像这样的模式:

var InstrumentSchema = new mongoose.Schema({
  name: String,
  description: String,
  parent: String
});
module.exports = mongoose.model('Instrument', InstrumentSchema);

它们都是乐器,所以都这样存储。我所说的“父”工具只会有一个空白的父值(即,它们没有父值)。但是,子类型仪器在该字段中具有“父”仪器的 _id。

所以,我最终可能会得到 ($ db.instruments.find()):

{ 
  _id: ObjectId("5508ae0e81a30b766fb8b679"),
  name: "Mandolin",
  description: "blah blah blah",
  parent: ""
},
{
   _id: ObjectId("5508ae0e81a30b766fb8b80"),
  name: "Mandola",
  description: "blah blah blah",
  parent: "5508ae0e81a30b766fb8b679"
},
{
   _id: ObjectId("5508ae0e81a30b766fb8b681"),
  name: "Octave Mandolin",
  description: "blah blah blah",
  parent: "5508ae0e81a30b766fb8b679"
}

所以后两个与前两个相关 - 通过“父”键。

我想请求第一个乐器,还有后两个(作为一个数组),最终得到如下内容:

{ 
  _id: ObjectId("5508ae0e81a30b766fb8b679"),
  name: "Mandolin",
  description: "blah blah blah",
  parent: ""
  sub-instruments: [
      { 
       _id: ObjectId("5508ae0e81a30b766fb8b80"),
      name: "Mandola",
      description: "blah blah blah",
      parent: "5508ae0e81a30b766fb8b679" 
      },
     {
       _id: ObjectId("5508ae0e81a30b766fb8b681"),
      name: "Octave Mandolin",
      description: "blah blah blah",
      parent: "5508ae0e81a30b766fb8b679"
    }
   ]
}

所以,我得到了主要仪器(这将是 IU 中的主显示器),以及一组子仪器(可以在下面列出 - 在列表或表格中)。

我已经扫描了 MongoDB 和 Mongoose 文档并查看了一些 SO 问题,但似乎没有任何答案 - 我当然希望这是可能的。现在我有一个主要仪器的查询,例如:

var instRoute = router.route('/instruments/:instrument_id');

instRoute.get(function(req, res) {
  Instrument.findById(req.params.insturment_id, function(err, instrument) {
    if (err) {
      return res.send(err);
        }
    res.render('instrument', { 
            instrument: instrument, 
            pageTitle: 'Instrument' // for the <title> tag
    });
  });
});

如何在其中插入子查询并将其添加到数组中返回的 JSON 中?好像我需要另一个 .find() 或者 MongoDB 文档中有关于 elemMatch 的内容(或者只是在哪里?)。我尝试过使用几种不同的东西,但没有任何效果。我只需要更新查询吗?或者 Instruments 的 Schema 是否也需要更改?

【问题讨论】:

  • 你看过猫鼬对population的支持吗?
  • 谢谢。当我扫描文档时,人群并没有引起我的注意——我不知道我在寻找什么。我会检查一下。

标签: mongoose


【解决方案1】:

就像@JohnnyHK 在他的评论中建议的那样,你可以看看 Mongoose 对 population 的支持。但是,您可以尝试使用当前架构的解决方法是首先找到父仪器,创建一个数组对象,然后您可以使用子仪器填充该对象,例如:

// Get the parent documents
var insturment_id = req.params.insturment_id;
Instruments.findOne({_id: insturment_id, parent:""}, function(err, instrument) {
    // Create an array that holds the sub instruments
    var sub_instruments = [];

    // Get the child instruments with parent
    Instruments.find({parent: insturment_id}, function(err, docs) {
        sub_instruments = docs;
    });

   instrument["sub-instruments"] = sub_instruments;
   if (err) {
      return res.send(err);
   }
   res.render('instrument', { 
        instrument: instrument, 
        pageTitle: 'Instrument' // for the <title> tag
   });
});

【讨论】:

  • 谢谢。跟我想的差不多,就是想不出来。它似乎不起作用。这里的第一个 console.log 按预期返回,第二个(在 sub_instrument 查询之外)什么也不显示:Instruments.find({parent: insturment_id}, function(err, docs) { sub_instruments = docs; console.log("First time: " + sub_instruments); }); console.log("Second time: " + sub_instruments);
  • 由于某种原因,上述方法不太有效,但几乎就在那里。我只需要取消嵌套查询。我将添加有效的答案-但它基于此答案。 :) 谢谢!
【解决方案2】:

我发现了一些有用的东西。我只需要取消嵌套 chridam 非常有用的回复中提供的查询。虽然,不知道为什么会有所作为。此外,将“父”查询改回.findById(),因为另一个建议导致了错误。

instrumentRoute.get(function(req, res) {
    // get parent instrument
    var instrument_id = req.params.instrument_id;

    // Create an array to hold the sub instruments
    var sub_instruments = [];

    // Get the child instruments
    Instrument.find({parent: instrument_id}, function(err, docs) {
        if (err) {
          return res.send(err);
        }
        sub_instruments = docs;
    });

    // Get parent and render all, with sub-insts added to object 
    Instrument.findById( instrument_id, function(err, instrument) { 
       if (err) {
        return res.send(err);
       } 
       res.render('instrument', { 
            instrument: instrument, 
            pageTitle: 'Instrument', // for the <title> tag
            sub_instruments: sub_instruments 
         });
    });
});

我会关注Populations 的未来。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 2017-08-15
    • 2013-09-04
    • 2013-03-19
    • 1970-01-01
    • 2015-05-29
    相关资源
    最近更新 更多