7

这是主体对象的架构:

var newsSchema = new Schema({
    headline: String,
    paragraph: String,
    imgURI: String,
    imgThumbURI: String,
    imgCaption: String,
    addedOn: Date,
    addedBy: {
        type: ObjectID,
        ref: 'usr'
    }
});
var News = mongoose.model('news', newsSchema);

...以及 addedBy 的架构:

var usr = new Schema({
    username: String,
    avatar: {
        type: ObjectID,
        ref: 'avtr'
    },
    href: String
});
var UserModel = mongoose.model('usr', usr);

到目前为止,一切都很好。所有作品。然后在 Angular 客户端中,我检索了一个新闻对象,但 addedBy 值不是所需的对象,而是一个 ObjectId:

{
    "headline":"Shocking news from the Neverland!",
    ...
    "addedBy":"520e9aac9ca114914c000003", // <-- the offender!!
    "addedOn":"2013-08-16T21:33:32.294Z",
    "_id":"520e9aac9ca114914c000001",
    "__v":0
}

当我想要这样的对象时:

{
    "headline":"Shocking news from the Neverland!",
    ...
    "addedBy":{
        "username":"Peter"
        "avatar":{
            "src":"../images/users/avatars/avatar1.png", 
            "ststus":"happy"}
        }
    "addedOn":"2013-08-16T21:33:32.294Z",
    "_id":"520e9aac9ca114914c000001",
    "__v":0
}

所以是的,我希望在将主体对象发送到角度客户端之前,将所有(无论多么深)嵌套的 ObjectId 替换为来自数据库的各自对象。我正在构建的 API 很深而且很复杂,如果 Angular 客户端可以从我的 Express 服务器接收一个准备好被扔进作用域的对象,那就太好了。
如何更改以下“/新闻”路线:

app.get('/news', function(req, res, next){
    News.
        find().
        exec(function(err, nws){
            if(err) {res.writeHead(500, err.message)}
            res.send(nws);
        });
});

为了做到这一点,我可以像这样从角度完全访问完整的(嵌套的)对象:

angular.module('App', ['ngResource'])
    .controller('NewsCtrl', function($scope, $resource){
        var News = $resource('/news');
        var news = News.query();
        $scope.news = news;
    });

然后在网站上访问这样的api:

<img class="avatar-img" src="{{ news[0].addedBy.avatar.src }}">

我非常感谢你的时间,干杯 Jared

4

1 回答 1

6

正如@WiredPrairie 所说,您需要使用填充函数Populate Mongoose Documentation

您的查询应如下所示:

app.get('/news', function(req, res, next){
    News.
        find().
        populate("addedBy").
        exec(function(err, nws){
            if(err) {res.writeHead(500, err.message)}
            res.send(nws);
        });
});

您可以使用 populate 执行许多不同的操作,例如仅带入“ addedBy”文档的用户名字段,您可以执行

populate("addedBy","username")

或者如果您不想带一个特定字段,请执行以下操作:

populate("addedBy","-username")
于 2013-08-17T05:18:57.527 回答