在mongoose中映射和从两个集合中获取数据

时间:2023-02-10 02:31:31

I have two collections User and Contact. User will request another user for contact and both userids will be stored in contact collection with status. I want to use the contact and user in many other places, so wrote separate models.

我有两个用户和联系人集合。用户将请求其他用户进行联系,并且两个用户ID将存储在具有状态的联系人集合中。我想在许多其他地方使用联系人和用户,因此编写了单独的模型。

Now I want to get user profile with contact object, the contact object should have the contact user information.

现在我想获取具有联系对象的用户配置文件,联系对象应该具有联系人用户信息。

User Schema

var UserSchema = new mongoose.Schema({
  name : { 
    type:String,
    default: '', 
    required:'Please fill name.',
    trim: true 
  },
  mobile : { 
    type:String, 
    required:'Please fill mobile', 
    unique:true,
    trim:true 
  },
  contacts:[{
    type: mongoose.Schema.ObjectId, 
    ref: 'Contact'
  }]
});

Contact Schema

var ContactSchema = new mongoose.Schema({
    owner: {
        type: mongoose.Schema.ObjectId, 
        ref: 'User'
    },
    user: {
        type: mongoose.Schema.ObjectId, 
        ref: 'User'
    },
    status: { 
        type:String, 
        default:'pending' 
    }
});

Profile API

User
   .findById(req.body.user_id)
   .populate({
     path: 'contacts',
     select: 'user',
   })
   .exec(function(err, user){
      if (err) return res.send(err);
      res.status(200).json({'message':'Profile found.','user':user});
   });

Here the response will be as follows:

这里的回复如下:

   {
        "message": "Profile found.",
        "user":
        {
            "_id": "563037f3fe2b69e40b05c451",
            "mobile": "32435345",
            "__v": 1,
            "contacts":
            [
                {
                    "_id": "56303f04f1b8524f0d03d9a7",
                    "user": "563037bafe2b69e40b05c44e"
                }
            ],
            "name": "Lorem"
        }
      }

In the contacts array, I need the name and mobile field for the connected user along with id. How can I achieve this? Or is there any other better approach in schema design?

在contacts数组中,我需要连接用户的名称和移动字段以及id。我怎样才能做到这一点?或者在架构设计中还有其他更好的方法吗?

1 个解决方案

#1


2  

You should try mongoose-deep-populate module.

你应该尝试mongoose-deep-populate模块。

var UserSchema = new Schema({
   name: String,
   mobile: String,
   contacts: [{type: mongoose.Schema.ObjectId, ref: 'Contact'}]
})

var ContactSchema = new Schema({
    owner: {
        type: mongoose.Schema.ObjectId, 
        ref: 'User'
    },
    user: {
        type: mongoose.Schema.ObjectId, 
        ref: 'User'
    },
    status: { 
        type:String, 
        default:'pending' 
    }
});

Initialize the module with a mongoose instance:

使用mongoose实例初始化模块:

var deepPopulate = require('mongoose-deep-populate')(mongoose);
UserSchema.plugin(deepPopulate, options /* more on options below */);

Now you can populate:

现在你可以填充:

User
.findById(req.body.user_id)
.deepPopulate(users, 'contacts.user', function (err, _users) {
  // _posts is the same instance as posts and provided for convenience 
  users.forEach(function (user) {
    // post.contacts and user.contacts.user are fully populated 
  });
});

#1


2  

You should try mongoose-deep-populate module.

你应该尝试mongoose-deep-populate模块。

var UserSchema = new Schema({
   name: String,
   mobile: String,
   contacts: [{type: mongoose.Schema.ObjectId, ref: 'Contact'}]
})

var ContactSchema = new Schema({
    owner: {
        type: mongoose.Schema.ObjectId, 
        ref: 'User'
    },
    user: {
        type: mongoose.Schema.ObjectId, 
        ref: 'User'
    },
    status: { 
        type:String, 
        default:'pending' 
    }
});

Initialize the module with a mongoose instance:

使用mongoose实例初始化模块:

var deepPopulate = require('mongoose-deep-populate')(mongoose);
UserSchema.plugin(deepPopulate, options /* more on options below */);

Now you can populate:

现在你可以填充:

User
.findById(req.body.user_id)
.deepPopulate(users, 'contacts.user', function (err, _users) {
  // _posts is the same instance as posts and provided for convenience 
  users.forEach(function (user) {
    // post.contacts and user.contacts.user are fully populated 
  });
});