【问题标题】:Mongoose - find objects which are NOT IN another list of objectsMongoose - 查找不在另一个对象列表中的对象
【发布时间】:2018-12-31 09:00:43
【问题描述】:

几天前我发布了this question。因为没找到 工作解决方案,我已经稍微改变了我的应用程序的结构,这就是为什么 我正在发布这个新问题。

UserTask 型号。一个User 包含两个Tasks 列表,它们是tasksAssignedtasksCompleted

user.model.js

const mongoose = require("mongoose");
const autopopulate = require("mongoose-autopopulate");
const UserSchema = mongoose.Schema({
  username: String,
  password: String,
  firstName: String,
  lastName: String,
  friends: [
    { type: mongoose.Schema.ObjectId, ref: "User", autopopulate: true }
  ],
  tasksAssigned: [
    { type: mongoose.Schema.ObjectId, ref: "Task", autopopulate: true }
  ],
  tasksCompleted: [
    { type: mongoose.Schema.ObjectId, ref: "Task", autopopulate: true }
  ]
  // TODO: When saving, use something like this: peter.subjects.push(math._id, computer._id)
});
UserSchema.plugin(autopopulate);
module.exports = mongoose.model("User", UserSchema);

task.model.js

const mongoose = require("mongoose");
const autopopulate = require("mongoose-autopopulate");    
const TaskSchema = mongoose.Schema({
  name: String,
  type: String,
  percentage: Number
});
TaskSchema.plugin(autopopulate);    
module.exports = mongoose.model("Task", TaskSchema);

我需要找到Tasks 的列表,这些列表分配给特定的User。在前端应用程序中,我有一个 task.service.js 方法:

function getAllUserTasksNotAssignedToUser(userId) {
  $http
    .get("http://localhost:3333/tasks/notAssignedToUser/" + userId)
    .then(function(response) {
      return response.data;
    });
}

在后端,有 task.routes.js,这里定义了这个路由:

app.get("/tasks/notAssignedToUser/:userId", tasks.findAllNotAssignedToUser);

...并且在 task.controller.js 中有一个相关的方法:

exports.findAllNotAssignedToUser = (req, res) => {
  console.log("Back controller call");
  User.findById(req.params.userId)
    .then(user => {
      Task.find({ _id: {$nin: user.tasksAssigned }}).then(tasks => {
        res.send(tasks);
      });
    })
    .catch(err => {
      res.status(500).send({
        message:
          err.message ||
          "Some error occurred while retrieving tasks not assigned to the user."
      });
    });
};

如您所见,我的想法是先找到特定的User,然后再找到不在该用户的tasksAssigned 列表中的所有Tasks。但是,出了点问题,在浏览器的控制台中我得到:

TypeError: Cannot read property 'then' of undefined
    at new AdminUserDetailsController (bundle.js:38254)
    at Object.instantiate (bundle.js:6395)
    at $controller (bundle.js:12447)
    at Object.link (bundle.js:1247)
    at bundle.js:2636
    at invokeLinkFn (bundle.js:11994)
    at nodeLinkFn (bundle.js:11371)
    at compositeLinkFn (bundle.js:10642)
    at publicLinkFn (bundle.js:10507)
    at lazyCompilation (bundle.js:10898) "<div ng-view="" class="ng-scope">"

实现这一点的正确方法是什么?

【问题讨论】:

    标签: mongoose mean-stack


    【解决方案1】:

    我创建了您的架构并填充了一些虚假数据:

      let task1 = new Task({
        name: 'task1',
        type: 'type1',
        percentage: '10'
      });
      task1.save();
      let task2 = new Task({
        name: 'task2',
        type: 'type2',
        percentage: '20'
      });
      task2.save();
      let task3 = new Task({
        name: 'task3',
        type: 'type3',
        percentage: '30'
      });
      task3.save();
    

    我在 tasksAssigned 字段中为此用户添加了两个任务(task1 和 task3):

    let user1 = new User({
        username: 'name teste',
          password: '123456',
        firstName: 'first name test',
        lastName: 'last name test',
        friends: [],
        tasksAssigned: ['5b579e94454cb206f6ca338f','5b579e94454cb206f6ca3391'],
        tasksCompleted: []});
      user1.save();
    

    并执行了您的代码。之后我发现只有一个问题,当你调用 Task.find 时,你需要检查 user 是否被找到,如果你不检查,你会在 user.tasksAssigned 行收到错误。

    User.findById('5b579ee41ac34e0763324fe3')
        .then(user => {
          if(user) {
            Task.find({_id: {$nin: user.tasksAssigned}}).then(tasks => {
              console.log(tasks);
              res.send(tasks);
            });
          }
        })
        .catch(err => {
          console.log('error');
          console.log(err);
          res.status(500).send({
            message:
            err.message ||
            "Some error occurred while retrieving tasks not assigned to the user."
          });
        });
    

    这是 Task then 方法中的控制台日志:

    这里是浏览器中路由的结果:

    在此链接中,您可以查看有关承诺的 Mongoose 文档:Mongoose Promises

    【讨论】: