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

Aggregate using external references in 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"
             }
        ]
        }        
    ]
}

但我无法使用书籍上的 $aggregate 查询 table 来填充出版商参考,我什至不知道这是否可行。

获得这种结果的正确策略是什么?

获得结果的一种方法是通过迭代每个出版商来找到他的书然后构造你的结果来模拟连接:)

样本 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.eval to run a query as Server-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 的示例:(在 collection 姓名簿上)

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));
  })
})