用mongoose和nodejs保存另一个文档的引用

时间:2019-02-21 02:57:14

标签: node.js mongodb mongoose

我是使用mongodb的新手,我正在使用ref进行练习并填充...但是我有一个愚蠢的问题。

我从客户那里收到了这样的对象。

    {
    "name": "Jhon"
    "books": [
              { 
                "title": "whatever",
                 "pages": 300
              },
              {
                "title": "otherBook",
                 "pages": 450
              }
             ]
    }

所以我有两个模式,authorSchema和booksSchema ...,所以我假装是保存书,并取每本书的_id来保存作者。

我在nodejs中的代码

authorCtrl.saveAuthor = (req, res) => {

    var booksId= []

    for (i = 0; i < req.body.books.length; i++) {
        booksModel.create(req.body.books[i], function (err, book) {
            booksId.push(book._id)
        })
    }

    var author= {
        name: req.body.name,
        books: booksId
    }

    console.log(author) // here i check and books array is empty,

    authorModel.create(author).then((authorSaved) => {
        res.json(authorSaved)
    }).catch(err => {
        res.json(err)
    })
}

我知道这是一个异步问题...但是我该怎么做?..或引用集合的最佳实践是什么?

////// EDIT //////

这是我的模式

作者架构

const mongoose = require('mongoose')
const { Schema } = mongoose;


const authorsSchema = new Schema({
    name: { type: String },
    books: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'books'
    }]
})


module.exports = mongoose.model('authors', authorsSchema);

Books Schema

const mongoose = require('mongoose')
const { Schema } = mongoose;


const booksSchema = new Schema({
    title: { type: String },
    pages: { type: Number }

})


module.exports = mongoose.model('books', booksSchema);

3 个答案:

答案 0 :(得分:1)

作者架构:

var url = "https://api.rewards.com:/lists/v1/listcontainer/1?ts=20190221004021&auth=EngineeringSolutions:ydvMMlY2uxiKG0yuwh1IbVgR2mfqTQaQncTEaMr+Ef0=";

//method 1: pure js
var queries = url.match(/(.+)\?(.+)/)[2].split("&");
var params  = {};

for (let i=0; i<queries.length; i++){
  var item = queries[i].match(/([0-9A-Za-z]+)=(.+)/);
  params[item[1]] = item[2]
}

console.log(JSON.stringify(params,null,2));

//method 2: new in ES6
var queryStr  = url.match(/(.+)\?(.+)/)[2];
var urlParams = new URLSearchParams(queryStr);
var params    = {};

for (let item of urlParams.entries())
  params[item[0]] = item[1];
  
console.log(JSON.stringify(params,null,2));

Books Schema:

const mongoose = require('mongoose')
const { Schema } = mongoose;

const authorsSchema = new Schema({
    name:  String,
    books: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Book'
    }]
})

module.exports = mongoose.model('Author', authorsSchema);

NodeJS代码:

const mongoose = require('mongoose')
const { Schema } = mongoose;

const booksSchema = new Schema({
    title: String,
    pages: Number,
})

module.exports = mongoose.model('Book', booksSchema);

答案 1 :(得分:0)

Try this,

authorCtrl.saveAuthor = (req, res) => {
var booksId= [];

for (var i = req.body.books.length - 1; i >= 0; i--) {
    booksModel.create(req.body.books[i], (err, book) => {
        booksId.push(book._id);
        if(i == 0) { // This if condition executes at the end of the for loop.
            var author= {
                name: req.body.name,
                books: booksId
            };

            console.log(author);

            authorModel.create(author).then((authorSaved) => {
                res.json(authorSaved);
            }).catch(err => {
                res.json(err);
            });
        }
    });
}

}

希望有帮助...

答案 2 :(得分:0)

您可以使用如下的Javascript许诺来做到这一点:

            var booksId = [];
            var promises = [];
            req.body.books.forEach(element => {
                promises.push(insertBook(element));
            });
            Promise.all(promises)    
            .then(function(data){ 
                /* do stuff when success */
                console.log('##GREAT##',booksId);
                /*** INSERT ARRAY OF BOOK IDs INTO authorModel***/
            })
            .catch(function(err){ 
                /* error handling */ 
            });

            function insertBook(element){
                return new Promise(function(resolve, reject){
                    var book = new booksModel({
                        title: element.title,
                        page:  element.page  
                    });

                    book.save(function(err,data){
                        if(err){
                            console.log(err);
                            reject(err)
                        }else{
                            console.log('#success');
                            booksId.push(data._id)
                            resolve();
                        }
                    });
                });
            }