使用mongodb中的外部引用进行聚合

时间:2015-02-12 10:01:51

标签: javascript mongodb

我想在mongodb查询中汇总结果,但是我无法在mongodb.org中建模的情况下完成此操作:

{
   _id: "oreilly",
   name: "O'Reilly Media",
   founded: 1980,
   location: "CA"
}

{
   _id: 123456789,
   title: "MongoDB: The Definitive Guide",
   author: [ "Kristina Chodorow", "Mike Dirolf" ],
   published_date: ISODate("2010-09-24"),
   pages: 216,
   language: "English",
   publisher_id: "oreilly"
}

{
   _id: 234567890,
   title: "50 Tips and Tricks for MongoDB Developer",
   author: "Kristina Chodorow",
   published_date: ISODate("2011-05-06"),
   pages: 68,
   language: "English",
   publisher_id: "oreilly"
}

我的结果应该有这样的结构:

{
    publishers: [
    {
        _id: "oreilly",
        name: "O'Reilly Media",
        founded: 1980,
        location: "CA"
        books: [
            {
                 _id: 123456789,
                 title: "MongoDB: The Definitive Guide",
                 author: [ "Kristina Chodorow", "Mike Dirolf" ],
                 published_date: ISODate("2010-09-24"),
                 pages: 216,
                 language: "English"
            },
            {
                 _id: 234567890,
                 title: "50 Tips and Tricks for MongoDB Developer",
                 author: "Kristina Chodorow",
                 published_date: ISODate("2011-05-06"),
                 pages: 68,
                 language: "English",
                 publisher_id: "oreilly"
             }
        ]
        }        
    ]
}

但我无法使用books表上的$ aggregate查询填充发布商参考,我甚至不知道是否可以。

获得此类结果的正确策略是什么?

1 个答案:

答案 0 :(得分:1)

获得结果的一种方法是通过迭代每个发布者来查找他的书来模拟联接,然后构建结果:)

mongo shell中的示例:

var publishers = []; 
var struct = {};
struct.publishers = publishers
db.publisher.find().forEach( function(publisher) {        
        publisher.books = db.books.find({publisher_id: publisher._id}).toArray()
        publishers.push(publisher)
})
printjson(struct)

司机样本:

您可以使用db.evalServer-side Javascript运行查询。

db.eval: connection.db.eval(function construct(publisher){return struct}), arg ,function (e, result) {result});
db.eval函数:

db.eval(function construct(publisher) {
    var publishers = []; 
    var struct = {};
    var query = publisher ? {_id:publisher} : {}
    struct.publishers = publishers
    db.publisher.find(query).forEach( function(publisher) {
        publisher.books = db.books.find({publisher_id: publisher._id}).toArray()
        publishers.push(publisher)
    })
return struct
}
,null // argument to pass into function for filter, e.g. 'oreilly'
,{nolock:true})

带有mongoose的样本:(在集合名称簿上)

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/book');
mongoose.connection.on('connected', function() {
  mongoose.connection.db.eval(function construct(publisher) {
      var publishers = [];
      var struct = {};
      var query = publisher ? {_id:publisher} : {}
      struct.publishers = publishers
      db.publisher.find(query).forEach( function(publisher) {
          publisher.books = db.books.find({publisher_id: publisher._id}).toArray()
          publishers.push(publisher)
      })
  return struct
  }
  ,'oreilly'
  ,{nolock:true}, function(e,result) {
    if(e) console.log(e);
    console.log(JSON.stringify(result));
  })
})