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

使用Mongoose/MongoDB检索文档和子文档,mongoose,Mongoose,使用Express.js熟悉MongoDB/Mongoose,我不知道如何查询它并获取所需的JSON 我有一份乐器的清单。有一些乐器是一种子类型,所以我将它们关联回一种乐器。因此,我有一个模式,看起来像: var InstrumentSchema = new mongoose.Schema({ name: String, description: String, parent: String }); module.exports = mongoose.model('Instrumen

使用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()
):

因此,后两个与前两个相关-通过“parent”键

我想请求第一个仪器,以及第二个仪器(作为一个数组),最后得到如下结果:

{ 
  _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文档,并查看了一些这样的问题,但似乎没有任何答案——我当然希望这是可能的。现在我有一个关于主要仪器的查询,如:

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
    });
  });
});
var instrue=router.route('/instruments/:instrument_id');
instRoute.get(函数(req,res){
仪表.findById(要求参数仪表id,功能(错误,仪表){
如果(错误){
返回res.send(err);
}
res.render('instrument',{
文书:文书,
pageTitle:“仪器”//用于标记
});
});
});

如何将子查询插入其中并将其添加到数组中返回的JSON中?似乎我需要另一个.find()或者MongoDB文档中有关于elemMatch的内容(或者只是一个where?)。我试过使用几种不同的东西,但都不管用。我是否只需要更新查询?或者仪器的模式也需要改变吗?

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

// 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
   });
});
//获取父文档
var Instrument_id=所需参数Instrument_id;
findOne({u-id:instrument\u-id,父:“},函数(err,instrument){
//创建一个包含子乐器的阵列
var子_工具=[];
//与家长一起获取子乐器
find({parent:instrument_id},函数(err,docs){
子工具=文件;
});
工具[“子工具”]=子工具;
如果(错误){
返回res.send(err);
}
res.render('instrument',{
文书:文书,
pageTitle:“仪器”//用于标记
});
});

我发现了一些有效的方法。我只需要取消chridam非常有用的回复中提供的查询。不过,我不知道为什么会有不同。另外,将“parent”查询改回
.findById()
,因为另一个建议导致了一个bug

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 
         });
    });
});
instrumentRoute.get(函数(req,res){
//获取母乐器
var仪表id=所需参数仪表id;
//创建一个阵列以容纳子乐器
var子_工具=[];
//把孩子们的乐器拿来
find({parent:Instrument\u id},函数(err,docs){
如果(错误){
返回res.send(err);
}
子工具=文件;
});
//获取父对象并渲染所有对象,并将子指令添加到对象
Instrument.findById(Instrument_id,function(err,Instrument){
如果(错误){
返回res.send(err);
} 
res.render('instrument',{
文书:文书,
pageTitle:'仪器',//用于标记
子仪器:子仪器
});
});
});

我将展望未来。

您有没有看过猫鼬对您的支持?谢谢。当我扫描文档时,人群并没有引起我的注意——我不知道我在寻找什么。我去查一下,谢谢。这与我当时的想法是一致的,只是无法解释。它似乎不起作用。这里的第一个console.log按预期返回,第二个(在sub_instrument查询之外)不显示任何内容:
Instruments.find({parent:instrument_id},function(err,docs){sub_Instruments=docs;console.log(“第一次:+sub_Instruments);});控制台日志(“第二次:+子仪器)由于某种原因,上面的方法不太管用,但几乎就在那里了。我只需要取消查询。我将添加有效的答案-但它是基于此答案的。:)谢谢
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 
         });
    });
});