Node Mongoose虚拟属性返回子匹配条件

时间:2017-08-16 14:54:17

标签: node.js mongodb mongoose

在Mongoose应用程序中,我可以使用虚函数来查找ref为children的对象。

我遇到的问题是,给定父对象与具有两个日期(start_date,end_date)的许多子对象具有ref关系。

父对象:

{
    "id": 12345,
    "children": [...] // <= A virtual property to the child objects below.
}

儿童对象

[{
    "parent": 12345,
    "start_date": "2016-01-01",
    "end_date":   "2016-02-01"
},
{
    "parent": 12345,
    "start_date": "2016-02-02",
    "end_date":   "2016-03-01"
}]

理想情况下,我希望有一个名为current的虚拟属性,它返回当前日期介于start_date和end_date之间的子对象。

例如,如果今天是&#34; 2016-02-20&#34;,我希望结果如下:

{
    "id": 12345,
    "children": [...], // <= A virtual property to the child objects below.
    "current": {
        "parent": 12345,
        "start_date": "2016-02-02",
        "end_date":   "2016-03-01"
    }
}

我尝试在虚函数中查找子属性,但似乎因为它是一个promise,它总是返回null。我不确定是否有更简单的方法可以做到这一点,但我真的很感激任何想法。

这是我尝试过的,但总是返回null。即使我登录到控制台并且结果显示在那里:

ParentSchema
.virtual('current')
.get(function () {
   var result = null;
   ChildModel.find({parent: this._id}, function (err, results) {
       // ... some logic here to find the correct item. (Omitted for brevity).
       result = foundItem;
   });
   return result;
})

非常感谢!

1 个答案:

答案 0 :(得分:1)

请记住,mongoose操作是异步的,因此您需要等待在获得结果之前调用它们的回调。

ParentSchema.virtual('current').get(function () {
    var result = null;
    ChildModel.find({parent: this._id}, function callback(err, children) {
        // ...
        result = child;
    });
    // by the time it reaches this point, the async function ^ will not yet be finished -- so result will always be null
    return result; 
})

(1)要使用虚拟属性,您必须返回Promise而不是值。

ParentSchema.virtual('current').get(function () {
    var self = this;
    return ChildModel.find({ parent: self._id }, function (err, children) {
        // ...
        self.current = child;
    });
})

然后你会像

一样使用它
parent.current.then(function () {
    console.log(parent.current);
}).catch(function (err) {
    // ...
})

(2)我认为最好使用一种方法。

ParentSchema.methods.getCurrent(function (callback) {
    var self = this;
    ChildModel.find({ parent: self._id }, function (err, children) {
        if (err) return callback(err);
        // ...
        self.current = child;
        callback();
    });
});

然后你会像

一样使用它
parent.getCurrent(function (err) {
    console.log(parent.current);
})