使用Mongoose / MongoDB检索文档和子文档

时间:2015-03-22 07:29:02

标签: mongoose

使用Express.js的MongoDB / Mongoose新手,我无法弄清楚如何查询并获取我需要的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(或者只是在哪里?)的东西。我尝试过使用几种不同的东西,但没有任何作用。我只需要更新查询吗?或者Schema for Instruments是否也需要改变?

2 个答案:

答案 0 :(得分:1)

我发现了一些有用的东西。我只需要解除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寻找未来。

答案 1 :(得分:0)

就像@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
   });
});