mongoose的population数据填充、关联不成功。

问题描述

根据这篇帖子https://segmentfault.com/a/1190000002727265弄的demo,提示这条语句js var userIds = [new ObjectId, new ObjectId, new ObjectId];new ObjectId是undefined,然后我删掉了跟new ObjectId相关字段的数据填充,然后代码如下:

const http = require('http');
const mongoose = require('mongoose');

var Schema   = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
//const _ObjectId = mongoose.Types.ObjectId;

// ==================User Schema=====================
var UserSchema = new Schema({
    name  : { type: String, unique: true },   
    posts : [{ type: ObjectId, ref: 'Post' }] // 要关联填充Post表的字段
});
var User = mongoose.model('User', UserSchema);

// ==================Post Schema=====================
var PostSchema = new Schema({
    poster   : { type: ObjectId, ref: 'User' }, // 要关联填充数据的字段
    comments : [{ type: ObjectId, ref: 'Comment' }], // 要关联填充数据的字段据
    title    : String,
    content  : String
});
var Post = mongoose.model('Post', PostSchema);

// ==================Comment Schema=====================
var CommentSchema = new Schema({
    post      : { type: ObjectId, ref: 'Post' },  // 要关联填充数据的字段据
    commenter : { type: ObjectId, ref: 'User' },  // 要关联填充数据的字段据
    content   : String
});
var Comment = mongoose.model('Comment', CommentSchema);


var db = mongoose.connect('mongodb://localhost/alan');

db.connection.on("error", (error) => { 
  console.log("数据库连接失败:" + error); 
}); 

db.connection.on("open", () => { 
  console.log("——数据库连接成功!——"); 
  // createData();
});

//创建数据并插入
function createData() {

    var users    ;
    var posts    ;
    var comments ;

    users = {
        name  : 'aikin',
        // posts : [new ObjectId]   // 因为ObjectId是未定义报错所以注释了
    };
    
    posts = {
        title    : 'post-by-luajin',
        // poster   : new ObjectId, // 因为ObjectId是未定义报错所以注释了
        // comments : [new ObjectId] // 因为ObjectId是未定义报错所以注释了
    };

    comments = {
        content   : 'comment-by-aikin',
        // commenter : new ObjectId,
        // post      : new ObjectId
    };

    var _user = new User(users);
    var _post = new Post(posts);
    var _comment = new Comment(comments);
    
    _user.save((err, user) => {
        if (err) console.log(err);
        console.log(user);
    });

    _post.save((err, post) => {
        if (err) console.log(err);
        console.log(post);
    });

    _comment.save((err, comment) => {
        if (err) console.log(err);
        console.log(comment);
    });

}

http.createServer((req, res) => {
    res.writeHead(200,{"Content-Type": "text/plain"});

    /*CN.findOne({name: 'Alan'}, (err, data) => {
        console.log(data);
    });*/
    User.find()
    .populate('posts', 'title')    
    .exec(function(err, docs) {
        console.log(docs); // 这里打印
        res.write("hello");
        res.end();
    });

    
}).listen(4000,() => {
    console.log("Server run at port", 4000);
});

在访问服务器时候执行createServer里面的代码,populate('posts', 'title')Post集合的title字段填充关联到User集合里的posts字段。但是打印效果是:

[ { name: 'aikin', _id: 595639aa9a73292826000001, posts: [] } ]
[ { name: 'aikin', _id: 595639aa9a73292826000001, posts: [] } ]

posts里数据为空是这么回事呢?

数据库里的数据

数据库里分别创建了User、Post、Comment三个表(集合),里面插入的数据如下:
User表的数据:

/* 0 */
{
    "name" : "aikin",
    "_id" : ObjectId("595639aa9a73292826000001"),
    "posts" : []
}

Post表的数据:

/* 0 */
{
    "title" : "post-by-luajin",
    "_id" : ObjectId("595639aa9a73292826000002"),
    "comments" : []
}

Comment表的数据:

/* 0 */
{
    "content" : "comment-by-aikin",
    "_id" : ObjectId("595639aa9a73292826000003")
}

为什么Post表少了poster,Comment表少了post字段呢?
使用population也填充不成功这么回事?刚接触mongdb有点蒙。

补充

补充一下,由于我的系统是win7 32位但目前的mongodb都不支持32位的,所以我装了个2012年的mongodb 2.0.4版本,和同时间段的mongoose 2.6.0版本

附数据库结构情况:
图片描述

阅读 4.9k
3 个回答

User.find().populate('posts', 'title')这个写法肯定是错的,
populate如果是string的话应该以空格分开吧(建议以object的方式多个分开写,不要把所有数据都populate出来),
而且用populate要你定义的表里的字段做了关联,你的title都不知道关联的什么,User表里根本没有这个字段

你的users集合的posts字段里都没有数据的,当然不能填充了,请尝试为posts数组字段内添加一个ObjectId再进行填充

请注意,posts字段里需要有对应的ObjectId值才能填充成功的,你看下你的是数据库集合内是否含有
clipboard.png

由于是低版本的MongoDB和Mongoose,没有仔细看这个问题。建议使用较新的版本的MongoDB和相应的NPM包。

不过在看过您问的问题后,如果我理解正确的话,您可能对Mongoose的population有理解上的偏差。

Mongoose的population只能进行collections之间的关联,相当于提供了一个手工ref的自动关联的功能;不支持collection之间的自动填充。换句话说,population仅仅支持读的操作,不支持写的操作;写入的时候,需要程序去照顾collection之间的reference的field的写入。

供参考。

Love MongoDB! Have fun!


重头戏要来了!MongoDB上海站用户大会在即!各种福利应接不暇!!!

WeChat_1495638544.jpeg

赶紧报名吧!
赶紧报名吧!
赶紧报名吧!

报名链接

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏