如何展开数组并在mongo中填充其详细信息?

问题描述 投票:0回答:1

我有assignments架构,如下所示:

const mongoose = require('mongoose');

const assignmentSchema = mongoose.Schema({
    name: String,
    document: String,
    startDate: Date,
    endDate: Date,
    trainingId: {type: mongoose.Schema.Types.ObjectId, ref: 'Training'},
    studentId: [{type: mongoose.Schema.Types.ObjectId, ref: 'User'}]
});

module.exports = mongoose.model('Assignment', assignmentSchema);

users架构如下图所示:

const mongoose = require('mongoose');

const userSchema = mongoose.Schema({
    firstName: String,
    lastName: String,
    phone: String
});

module.exports = mongoose.model('User', userSchema); 

我正在尝试根据ids数组中的studentId填充用户详细信息

const User = require('../models/user');
exports.assignments_get_unwindstud_based = (req, res, next) => {
  Assignment.aggregate(
    [
      {
        $unwind: "$studentId"
      },
      {
        "$lookup": {
          "from": User.collection.name,
          "localField": "studentId",
          "foreignField": "_id",
          "as": "studentDetails"
        }
      }
    ], function (err, result) {
        if (err) {
        console.log(err);
        return;
        }
        res.json(result); 
    });
};

但是,结果studentDetails数组显示空白而不是填充,并为每个training创建多个对象

[
    {
        "_id": "5ad4b1394935de1d5064a8bd",
        "studentId": "5ad58e4e151d1b10b850cc16",
        "name": "assignment1",
        "trainingId": "5ad59b231844ba1d60c2c976",
        "studentDetails": []
    },
    {
        "_id": "5ad4b1394935de1d5064a8bd",
        "studentId": "5ad58fed7c0d6614d80ffda9",
        "name": "assignment1",
        "trainingId": "5ad59b231844ba1d60c2c976",
        "studentDetails": []
    }
]

预期产量:

[
    {
        "_id": "5ad4b1394935de1d5064a8bd",
        "studentId": ["5ad58e4e151d1b10b850cc16"],
        "name": "assignment1",
        "trainingId": "5ad59b231844ba1d60c2c976",
        "studentDetails": [
          { ...Student details },
          { ...Student details }
        ]
    }
]

enter image description here enter image description here我在哪里做错了?

node.js mongodb express
1个回答
1
投票

真的不清楚你的问题究竟是什么,所以最好只用自包含的列表进行演示。除了主机和数据库命名空间的uri以及可能的身份验证凭据之外,您确实不需要更改所提供代码中的任何内容。

您应该选择与您的应用程序使用的数据库命名空间不同的数据库命名空间,因为此处的自包含测试旨在破坏任何现有数据。

现代nodejs发布过7.x:

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

const uri = 'mongodb://localhost/schooling';

mongoose.Promise = global.Promise;
mongoose.set('debug', true);

const userSchema = new Schema({
  firstName: String,
  lastName: String,
  email: String,
});

const assignmentSchema = new Schema({
  studentIds: [{ type: Schema.Types.ObjectId, ref: 'User' }],
  name: String,
  startDate: { type: Date, default: Date.now }
});

const User = mongoose.model('User', userSchema);
const Assignment = mongoose.model('Assignment', assignmentSchema);

const log = data => console.log(JSON.stringify(data, undefined, 2));

(async function() {
  try {

    const conn = await mongoose.connect(uri);

    await Promise.all(Object.entries(conn.models).map(([k,m]) => m.remove()));

    let users = await User.insertMany(
      ["aaa", "bbb"].map(el => ({ firstName: el, lastName: el, email: `${el}@example.com` }) )
    );

    log(users);

    await Assignment.create({
      studentIds: users,
      name: 'test 1'
    });

    let results = await Assignment.aggregate([
      { "$lookup": {
        "from": User.collection.name,
        "localField": "studentIds",
        "foreignField": "_id",
        "as": "studentDetails"
      }}
    ]);

    log(results);

    mongoose.disconnect();

  } catch(e) {
    console.error(e);
  } finally {
    process.exit();
  }
})();

或者返回几个版本:

const mongoose = require('mongoose'),
      Schema = mongoose.Schema;

const uri = 'mongodb://localhost/schooling';

mongoose.Promise = global.Promise;
mongoose.set('debug', true);

const userSchema = new Schema({
  firstName: String,
  lastName: String,
  email: String,
});

const assignmentSchema = new Schema({
  studentIds: [{ type: Schema.Types.ObjectId, ref: 'User' }],
  name: String,
  startDate: { type: Date, default: Date.now }
});

const User = mongoose.model('User', userSchema);
const Assignment = mongoose.model('Assignment', assignmentSchema);

const log = data => console.log(JSON.stringify(data, undefined, 2));

mongoose.connect(uri)
  .then(conn =>   Promise.all(Object.keys(conn.models).map(k => conn.models[k].remove())))
  .then(() =>User.insertMany(
    ["aaa", "bbb"].map(el => ({ firstName: el, lastName: el, email: `${el}@example.com` }) )
  ))
  .then(users => {
    log(users);
    return Assignment.create({
      studentIds: users,
      name: 'test 1'
    })
  })
  .then(() => Assignment.aggregate([
    { "$lookup": {
      "from": User.collection.name,
      "localField": "studentIds",
      "foreignField": "_id",
      "as": "studentDetails"
    }}
  ]))
  .then( results => log(results) )
  .then(() => mongoose.disconnect() )
  .catch( e => console.error(e) )
  .then(() => process.exit());

您应该在它自己的项目文件夹中设置它,没有其他依赖项,基本上只是npm install基于以下package.json与该列表一起出现在该文件夹中:

{
  "name": "schooling",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "mongoose": "^5.0.15"
  }
}

所以这真的只是mongoose,它是直接依赖安装,没有别的。

任何人都应该按照以下方式给你输出:

Mongoose: users.remove({}, {})
Mongoose: assignments.remove({}, {})
Mongoose: users.insertMany([ { _id: 5ad71e821d7f7b05c0316bb0, firstName: 'aaa', lastName: 'aaa', email: '[email protected]', __v: 0 }, { _id: 5ad71e821d7f7b05c0316bb1, firstName: 'bbb', lastName: 'bbb', email: '[email protected]', __v: 0 } ], {})
[
  {
    "_id": "5ad71e821d7f7b05c0316bb0",
    "firstName": "aaa",
    "lastName": "aaa",
    "email": "[email protected]",
    "__v": 0
  },
  {
    "_id": "5ad71e821d7f7b05c0316bb1",
    "firstName": "bbb",
    "lastName": "bbb",
    "email": "[email protected]",
    "__v": 0
  }
]
Mongoose: assignments.insert({ studentIds: [ ObjectId("5ad71e821d7f7b05c0316bb0"), ObjectId("5ad71e821d7f7b05c0316bb1") ], _id: ObjectId("5ad71e821d7f7b05c0316bb2"), name: 'test 1', startDate: new Date("Wed, 18 Apr 2018 10:31:30 GMT"), __v: 0 })
Mongoose: assignments.aggregate([ { '$lookup': { from: 'users', localField: 'studentIds', foreignField: '_id', as: 'studentDetails'
} } ], {})
[
  {
    "_id": "5ad71e821d7f7b05c0316bb2",
    "studentIds": [
      "5ad71e821d7f7b05c0316bb0",
      "5ad71e821d7f7b05c0316bb1"
    ],
    "name": "test 1",
    "startDate": "2018-04-18T10:31:30.839Z",
    "__v": 0,
    "studentDetails": [
      {
        "_id": "5ad71e821d7f7b05c0316bb0",
        "firstName": "aaa",
        "lastName": "aaa",
        "email": "[email protected]",
        "__v": 0
      },
      {
        "_id": "5ad71e821d7f7b05c0316bb1",
        "firstName": "bbb",
        "lastName": "bbb",
        "email": "[email protected]",
        "__v": 0
      }
    ]
  }
]

这清楚地表明"users"集合中的项目被$lookup返回到数组目标中。

如果不出意外,这应该为您提供诊断当前环境中出现问题的基础,因为您可以通过比较了解事情是如何完成的。

© www.soinside.com 2019 - 2024. All rights reserved.