首页 > 解决方案 > Mongoose 找不到所需的输出

问题描述

我有三个模式。

用户.js:

const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    unique: true,
    required: true,
  },
  password: {
    type: String,
    required: true,
  },
});

userSchema.pre("save", function (next) {
  const user = this;
  if (!user.isModified("password")) {
    return next();
  }

  bcrypt.genSalt(10, (err, salt) => {
    if (err) {
      return next(err);
    }
    bcrypt.hash(user.password, salt, (err, hash) => {
      if (err) {
        return next(err);
      }
      user.password = hash;
      next();
    });
  });
});

userSchema.methods.comparePassword = function (candidatePassword) {
  const user = this;
  return new Promise((resolve, reject) => {
    bcrypt.compare(candidatePassword, user.password, (err, isMatch) => {
      if (err) {
        return reject(err);
      }

      if (!isMatch) {
        return reject(false);
      }

      resolve(true);
    });
  });
};

mongoose.model("User", userSchema);

项目.js:

const mongoose = require("mongoose");

const diamondSchema = new mongoose.Schema({
  criteria: {
    novelty: String,
    technology: String,
    complexity: String,
    pace: String,
  },
});

const projectSchema = new mongoose.Schema({
  userId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
  },
  projectName: {
    type: String,
    default: "",
  },
  projectBudget: {
    type: Number,
  },
  projectDuration: {
    type: Number,
  },
  industry: {
    type: String,
  },
  companyName: {
    type: String,
  },
  numberOfEmployees: {
    type: Number,
  },
  diamond: [diamondSchema],
});

mongoose.model("Project", projectSchema);

推荐.js:

const mongoose = require("mongoose");

const diamondSchema = new mongoose.Schema({
  criteria: {
    novelty: String,
    technology: String,
    complexity: String,
    pace: String,
  },
});

const recommendationSchema = new mongoose.Schema({
  diamond: [diamondSchema],
  description: {
    type: String,
  },
});

mongoose.model("Recommendation", recommendationSchema);

和两个路由文件。

authRoutes.js:

const express = require("express");
const mongoose = require("mongoose");
const User = mongoose.model("User");
const jwt = require("jsonwebtoken");

const router = express.Router();

router.post("/signup", async (req, res) => {
  const { name, email, password } = req.body;

  try {
    const user = new User({ name, email, password });

    await user.save();

    const token =
      //token has payload-->user id
      jwt.sign({ userId: user._id }, "MY_SECRET_KEY");

    res.send({ token });
  } catch (err) {
    //invalid data
    return res.status(422).send(err.message);
  }
});

router.post("/signin", async (req, res) => {
  const { email, password } = req.body;

  if (!email || !password) {
    return res.status(422).send({ error: "Must provide email and password" });
  }
  const user = await User.findOne({ email });
  if (!user) {
    return res.status(404).send({ error: "Invalid email or password" });
  }

  try {
    await user.comparePassword(password);
    const token = jwt.sign({ userId: user._id }, "MY_SECRET_KEY");
    res.send({ token });
  } catch (err) {
    return res.status(422).send({ error: "Invalid email or password" });
  }
});

module.exports = router;

项目路由.js:

const express = require("express");

const mongoose = require("mongoose");

const requireAuth = require("../middlewares/requireAuth");

const Project = mongoose.model("Project");
const Recommendation = mongoose.model("Recommendation");
const router = express.Router();

router.use(requireAuth);

router.get("/projects", async (req, res) => {
  const projects = await Project.find({ userId: req.user._id });
  res.send(projects);
});

router.post("/projects", async (req, res) => {
  const {
    projectName,
    projectBudget,
    projectDuration,
    industry,
    companyName,
    numberOfEmployees,
    diamond,
  } = req.body;

  if (
    !projectName ||
    !projectBudget ||
    !projectDuration ||
    !industry ||
    !companyName ||
    !numberOfEmployees ||
    !diamond
  ) {
    return res.status(422).send({ error: "Must provide all project details" });
  }

  try {
    const project = new Project({
      projectName,
      projectBudget,
      projectDuration,
      industry,
      companyName,
      numberOfEmployees,
      diamond,
      userId: req.user._id,
    });

    await project.save();

    //res.send(project);
  } catch (err) {
    res.status(422).send({ error: err.message });
  }
  try {
    const rec = await Recommendation.find({ diamond });
    //console.log(diamond);
    console.log(description);
    res.send(rec);
  } catch (err1) {
    res.status(422).send({ error: err1.message });
  }
});

module.exports = router;

使用邮递员,在 projectRoutes.js 文件中,当我尝试在 上发送发布请求时 localhost:3000/projects,我正在尝试创建一个新项目并作为我想要的响应description。我的逻辑是,在我将新项目保存在projects集合中之后,我试图在集合中找到具有 SAME DIAMOND OBJECT 的文档,该文档也存在于criteria集合中。意思是,我在收藏和收藏中有预定义的记录::recommendationsprojectsrecommendationsprojects

建议集合

项目集合

所以我需要一些方法,以便当我尝试为用户添加新项目时,我设置的数组中的criteria对象与预定义的文档之一中的数组中diamond的条件对象匹配,并且在发布请求中我可以返回作为响应。正如我在 中所做的那样,它显示为未定义。我不知道为什么。希望这是有道理的。diamondrecommendationslocalhost:3000/projectsdescriptionconsole.log(description)projectRoutes.js

基本上,这个想法是具有独特标准的推荐数量有限。因此,每当根据标准创建新项目时,都会向用户显示推荐。

标签: javascriptnode.jsmongodbexpressmongoose

解决方案


假设您在项目和推荐中只有一个数组元素

const {
  projectName,
  projectBudget,
  projectDuration,
  industry,
  companyName,
  numberOfEmployees,
  diamond,
} = req.body;

const [projectDiamond] = diamond // get the first object in the diamond array
const { criteria } = projectDiamond // extract criteria

const recommendation = await Recommendation.find({ 'diamond.criteria': criteria });

请注意,条件字段的顺序必须匹配,因为我们正在数组中查找匹配的对象。

参考:https ://docs.mongodb.com/manual/tutorial/query-arrays/#query-an-array


推荐阅读