Mongoose填充查找ObjectId数组

时间:2016-12-05 22:13:46

标签: node.js mongodb mongoose nosql

在使用Mongoose进行查找时,我正在尝试填充一个ObjectIds数组。

以下是models/comment.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// set up a mongoose model
var CommentSchema = new Schema({
    comment: {
        type: String,
        unique: false,
        required: true
    },
    date: { 
        type: Date, 
        default: new Date()
    },
});

module.exports = mongoose.model('Comment', CommentSchema);

以下是models/question.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Comment = require('./comment');


// set up a mongoose model
var QuestionSchema = new Schema({
    title: {
        type: String,
        unique: false,
        required: true
    },
    question: {
        type: String,
        required: true
    },
    plus: {
        type: Number,
        required: true,
        default: 0
    },
    minus: {
        type: Number,
        required: true,
        default: 0
    },
    date: { 
        type: Date, 
        default: new Date()
    },
    comments:[
        {type: Schema.Types.ObjectId, ref: 'Comment'}
    ]
});

module.exports = mongoose.model('Question', QuestionSchema);

以下是index.js

var express     = require('express');
var app         = express();
var request     = require('request-promise');
var bodyParser  = require('body-parser');
var morgan      = require('morgan');
var mongoose    = require('mongoose');
var passport      = require('passport');
var config      = require('./config/database'); // get db config file
var User        = require('./models/user'); // get the mongoose model
var Room        = require('./models/room'); // get the mongoose model
var Comment    = require('./models/comment'); // get the mongoose model
var Question    = require('./models/question'); // get the mongoose model
var port        = process.env.PORT || 5000;
var jwt         = require('jwt-simple');
var http        = require('http');
var io          = require('socket.io');
var server      = http.createServer(app);
var io          = io.listen(server);



// get our request parameters
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

// log to console
app.use(morgan('dev'));

// Use the passport package in our application
app.use(passport.initialize());

// Set the port
app.set('port', port);

//App files located in /public
app.use(express.static(__dirname + '/public'));

// views is the directory for all template files
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');

// The root url of the website serves the Angular app
app.get('/', function (request, response) {
  response.render('pages/index');
});

// connect to database
mongoose.connect(config.database);

// pass passport for configuration
require('./config/passport')(passport);

var roomService = require('./controllers/roomservice.js');
roomService.setup(io);

// connect the api routes under /api/*
app.use('/api', apiRoutes);

// Start the Express app
server.listen(app.get('port'), function () {
  console.log('Node app is running on port', app.get('port'));
});

以下是controllers/roomservice.js

function RoomService(){
    var socketio;
    var Comment = require('../models/comment'); // get the mongoose model
    var Question = require('../models/question'); // get the mongoose model
    var Room = require('../models/room'); // get the mongoose model

    function setup(io){
        socketio = io;
        socketio.on("connection", function(socket){
            socket.on('joinRoom', function(msg){
                console.log("joinRoom");
                socket.join(msg.room)
                Question.find({})
                    .exec(function(err, questions) {
                        for(var question in questions){
                            for(var comment in questions[question].comments){
                                questions[question].comments[comment] = Comment.find({ "_id": questions[question].comments[comment]});
                            }
                        }
                        socket.emit("listQuestions", questions)
                });
            });
            socket.on('addQuestion', function(msg){
                console.log("addQuestion");
                var question = new Question({
                    title: msg.title,
                    question: msg.question
                });
                // save the question
                question.save(function(err) {
                    if (err) throw err;
                    io.to(msg.room).emit("addQuestion", question);
                });
            });
            socket.on('addComment', function(msg){
                var comment = new Comment({
                    comment: msg.comment
                });
                // save the comment
                Question.findOne({_id: msg.question}, function(err, question){
                    if (err) throw err;
                    question.comments.push(comment);
                    question.save(function(err) {
                        if (err) throw err;
                        io.to(msg.room).emit("addComment", comment);
                        console.log(question);
                    });
                });
            });
            socket.on('addPlus', function(msg){
                // save the comment
                Question.findOne({_id: msg.question}, function(err, question){
                    if (err) throw err;
                    question.plus = question.plus + 1;
                    question.save(function(err) {
                        if (err) throw err;
                        io.to(msg.room).emit("addPlus", question);
                    });
                });
            });
            socket.on('addMinus', function(msg){
                // save the comment
                Question.findOne({_id: msg.question}, function(err, question){
                    if (err) throw err;
                    question.minus = question.minus + 1;
                    question.save(function(err) {
                        if (err) throw err;
                        io.to(msg.room).emit("addMinus", question);
                    });
                });
            });
        });
    }

    return{
        setup: setup
    }
}

module.exports = new RoomService();

我正在尝试在返回问题列表时填充注释数组。我用Mongoose的populate方法尝试了它,但它返回一个空的注释数组。

Question.find({}).populate("comments")
                    .exec(function(err, questions) {

                        socket.emit("questions", questions)
                });

当我没有使用填充方法时,我会得到类似这样的内容:

[{"title": "test", "comments": ["1253454", "654654747"]},
 {"title": "test", "comments": ["1253454", "654654747"]}]

但我想要这样的事情:

[{"title": "test", "comments": [{"comment": "test"}, {"comment": "test2"}]},
 {"title": "test", "comments": [{"comment": "test"}, {"comment": "test2"}]}]

我做错了什么?

1 个答案:

答案 0 :(得分:0)

你的猫鼬版本是什么?版本4.7.1对我来说没问题:

import { connDb } from './base';
import { model, Schema, SchemaTypes, disconnect } from 'mongoose';

const Question = model<any>('Question', new Schema({
  title   : SchemaTypes.String,
  comments: [
    {
      type: SchemaTypes.ObjectId,
      ref : 'Comment',
    },
  ],
}))
const Comment  = model<any>('Comment', new Schema({
  comment: SchemaTypes.String,
}))

connDb().then(() => Promise.all([
  Comment.remove({}),
  Question.remove({}),
])).then(() => Comment.insertMany([
  {
    comment: 'hello',
  },
  {
    comment: 'world',
  }
])).then((data: any[]) => Question.insertMany([
  {
    title   : 'question',
    comments: data.map((item: any) => item._id),
  }
])).then(() => Question.find({}).populate('comments').exec()).then((d) => {
  console.log(JSON.stringify(d))
}).then(() => disconnect())

结果是:

+ ts-node ./src/__test__/pop_comment.ts
[{"_id":"5846322e69db6c1ec86ac5fd","__v":0,"title":"question","comments":[{"_id":"5846322e69db6c1ec86ac5fb","__v":0,"comment":"hello"},{"_id":"5846322e69db6c1ec86ac5fc","__v":0,"comment":"world"}]}]