簡體   English   中英

貓鼬裁判不填充json

[英]Mongoose refs not populating json

我正在嘗試通過簡單的Express API學習MongoDB。 該API非常適合於獲取單個集合,但是當我嘗試使用mongoose ref將多個集合組合到一個架構中時,我得到一個僅包含_id字段的json響應。

這是Mongoose中的兩個模式:

var LinkSchema = require('./link.js');

var MyInfoSchema = new Schema({
    name: String,
    title: String,
    links: [ LinkSchema ]
});

var AboutSchema = new Schema({
    img: String,
    description: String
});

這些在端點上分別調用它們的工作正常。

我想要一個將這兩個集合合並為一個json響應的端點。 因此,我使用ref制作了此模型

var MyInfoSchema = require('./myinfo.js');
var AboutSchema = require('./about.js');

var AllDataSchema = new Schema({
    myinfo: {
        type: mongoose.Schema.ObjectId,
        ref: 'MyInfoSchema'
    },
    about: { 
        type: mongoose.Schema.ObjectId,
        ref: 'AboutSchema'
    }
});

我的Express API路由如下所示

var router = express.Router();

router.route('/')
    .get(function(request, response){
        var data = new AllData();

        // add myinfo
        MyInfo.findOne(function(error, info){
            data.myinfo = info;
            console.log(data); // this gives an id
        });

        // add about
        About.findOne(function(error, about){
            data.about = about;
        });

        console.log(data); // this prints nothing
        response.json(data);
    });

但是,我得到的json響應只是一個_id

 { "_id": "59bfed783f0ba490a34c9ce9" } 

為什么未填充響應?

我嘗試登錄到控制台。 當我將日志放入findOne() ,我得到了這樣的對象

{ _id: 59bfed783f0ba490a34c9ce9,
  myinfo: 59b1ad02d551330000000002 }

當我將log語句放置在find函數之外並且在response.json()之前時,我什么也沒得到。 這是為什么? data仍應在范圍內,不是嗎?

編輯:

正如@Mikey在答案中所建議的那樣,我已經重構為使用Promises。 距離越來越近,但是有兩個問題。 1.每個集合的鍵都缺失,並且2.它正在為根結構而不是對象返回一個數組。

這是更新

.get(function(request, response){
    var data = new AllData();

    var p1 = MyInfo.findOne().exec(),
        p2 = Navigation.findOne().exec(),
        p3 = About.findOne().exec(),
        p4 = Contact.findOne().exec();

    Promise.all([p1, p2, p3, p4]).then(function(data) {
        data.myinfo = data[0];
        data.navigation = data[1];
        data.about = data[2];
        data.contact = data[3];
        response.json(data);
    });
});

這是回應

[
    {
        "_id": "59b1ad02d551330000000002",
        "title": "Television Tester",
        "name": "Walter P. K.",
        "__v": 0,
        "links": [
            {
                "name": "...",
                "url": "...",
                "_id": "59b1ad02d551330000000004"
            },
            {
                "name": "more...",
                "url": "more...",
                "_id": "59b1ad02d551330000000003"
            }
        ]
    },
    {
        "_id": "59b2e606103ace0000000003",
        "__v": 1,
        "links": [
            {
                "name": "About",
                "url": "#",
                "_id": "59b2e62d103ace0000000009"
            },
            {
                "name": "Stuff",
                "url": "#",
                "_id": "59b2e62d103ace0000000008"
            },
            {
                "name": "Contact",
                "url": "#",
                "_id": "59b2e62d103ace0000000007"
            }
        ]
    }
    ...
]

應該是這樣的

{
  myinfo: {}.
  navigation: {},
  about: {},
  contact: {}
}

貓鼬操作是異步的。 您需要等待所有操作完成后才能發送響應。

您可以嵌套操作

router.route('/').get(function(request, response){
    var data = new AllData();

    MyInfo.findOne(function(err, info) {
        data.myinfo = info;
        About.findOne(function (err, about){
            data.about = about;
            response.json(data);
        });
    });
});

或使用諾言(我認為是這樣)

router.route('/').get(function(request, response){
    var data = new AllData();

    var p1 = MyInfo.findOne().exec(),
        p2 = About.findOne().exec();

    Promise.all([p1, p2]).then(function(data) {
        data.myinfo = data[0];
        data.about = data[1];
        response.json(data);
    });
});

findOne是異步的,因此您的控制台日志在findOne回調之前運行。

您可能正在尋找類似這樣的東西,它將查詢“ AllData”集合並將存儲的ID替換為引用的文檔中的“ myinfo”和“ about”:

AllData.find()
  .populate('myinfo about')
  .exec(function(error, docs) {
    console.log(docs)
    response.json(docs)
  });

我能夠通過其他答復者的有用建議來解決該問題。 感謝您指出find()和promises的異步特性。 我需要使其工作的是對響應結構(而不​​是Mongoose Schema)使用普通的JS對象,並進行一些變量名清除。 在Mikey的答案中,以及我對該問題的編輯中,返回的response和console.log數組實際上是promises數組(即p1,p2,p3等的值),而不是我想要返回的數據結構。

這是工作代碼:

router.route('/')
    .get(function(request, response){

        var p1 = MyInfo.findOne().exec(),
            p2 = Navigation.findOne().exec(),
            p3 = About.findOne().exec(),
            p4 = Contact.findOne().exec();

        Promise.all([p1, p2, p3, p4]).then(function(docs) {
            var data = {};
            console.log(docs);
            data.myinfo = docs[0];
            data.navigation = docs[1];
            data.about = docs[2];
            data.contact = docs[3];
            response.json(data);
        });
    });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM