【问题标题】:How to select two table (document) value at a time by user id in mongoose?如何通过猫鼬中的用户ID一次选择两个表(文档)值?
【发布时间】:2020-01-10 00:46:10
【问题描述】:

我正在使用 NodeJs、ExpressJs 与 Mongodb 和 Mongoose。我想通过用户 ID 选择两个文档的值。

我有三个模型用户,学术和职业。我通过用户模式的 _id 与学术和职业模式建立了关系。我在这些文档中保存了一些值。现在我想通过用户 ID 选择学术和职业的文档值。

型号

 // user model
    const userSchema = new mongoose.Schema({
        name: {type: String},
        email: {type: String},
    });
    const user = mongoose.model('User', userSchema);

    // academic model
    const academicSchema = new mongoose.Schema({
        academicLevel: {type: String},
        passYear: {type: Number},
        user: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        }
    });
    const academic = mongoose.model('Academic', academicSchema);

    // career model
    const careerSchema = new mongoose.Schema({
        jobTitle: {type: String},
        company: {type: String},
        user: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        }
    });
    const career = mongoose.model('Career', careerSchema);

文件

// user documents

_id: objectId("5d0df6a4134d4d295ca9f212")
name: "John Doe"
email: "john@gmail.com"

_id: objectId("5d0e70a6c87ca528c0a79a0f")
name: "Mark Boucher"
email: "mark@gmail.com"


// academic documents

_id: objectId("5d60bc7188a8ef3648b8e8cf")
academicLevel: "Master"
passYear: "2018"
user: objectId("5d0e70a6c87ca528c0a79a0f")

_id: objectId("5d60d56f0cf9af32901cb2aa")
academicLevel: "Bachelor"
passYear: "2016"
user: objectId("5d0e70a6c87ca528c0a79a0f")

// career documents

_id: objectId("5d60bc1d88a8ef3648b8e8ce")
jobTitle: "Software Engineer"
company: "Daffodil Software Ltd."
user: objectId("5d0e70a6c87ca528c0a79a0f")

nodejs

router.get('/getInfoById', async (req, res) => {
    const user = await User
    .find(req.query.id)
    .select()

    res.send(user);
})

如何通过用户 ID 从两个文档(学术和职业)中获取值。谢谢。

【问题讨论】:

  • 你想要两个不同的查询还是想要一个查询来获得解决方案?
  • 我想要单个查询
  • 您使用的是哪个版本的 MongoDB?需要聚合查询吗?
  • 版本:4.0.9。我不知道聚合查询。我是 Mongodb 和 mongoose 的新手
  • 我认为最佳做法是使用 2 个查询,正如答案中所建议的那样。

标签: javascript node.js mongodb mongoose


【解决方案1】:

对于我在文档中阅读的内容,我认为您正在寻找的是这样的:

const career = await Career.find({ user: user._id});
const academics = await Academics.find({ user: user._id});

或者如果您想同时执行两个查询:

const careerOperation = Career.find({ user: user._id});
const academicsOperation = Academics.find({ user: user._id});

const [
    career, 
    academics
] = await Promise.all([career.exec(), academics.exec()]);

希望有所帮助!

【讨论】:

  • 当我发现它时,我觉得它太棒了。但请注意,如果数组中有两个以上的元素,我建议将它放在一个变量中并在每个逗号后中断
  • 两年前,我找到了使用这种语法的解决方案。从那天起,我总是只使用这种语法来解决 promise。谢谢兄弟。
  • @VitorRibeiro 我以这种方式使用了您的解决方案代码: router.get('/getInfoById', async (req, res) => { const career = Career.find({user: req. query.user}); const Academic = Academic.find({ user: req.query.user}); await Promise.all([career.exec(), Academic.exec()]); res.send(career) ; res.send(academic); }) 但我得到了一个错误。错误是:UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:1):TypeError:将循环结构转换为 JSON
  • 我忘记在我的答案中添加一些内容,我会立即更新它!只有一个注意事项,不要在同一个请求上调用 res.send 两次,最好在嵌套你想要传递的对象时调用它: res.send({career, Academics});
  • @VitorRibeiro 你美!非常感谢兄弟。我为此花了很多时间。至少我明白了。
【解决方案2】:

由于这里使用了Mongoose:这可以使用Populate 来实现。 populate 与您在纯 mongo 中通过 $lookup 聚合实现的非常相似/类似。

另一种选择:如果您要像这样调整架构以真正利用 Mongoose

//user model
const userSchema = new mongoose.Schema({
  name: { type: String },
  email: { type: String },
  career: {
    type: Schema.Types.ObjectId,
    ref: "Career"
  },
  academic: {
    type: Schema.Types.ObjectId,
    ref: "Academic"
  }
});

//academics and career can be array of documents as well -if required
const user = mongoose.model("User", userSchema);

// academic model
const academicSchema = new mongoose.Schema({
  academicLevel: { type: String },
  passYear: { type: Number }
});
const academic = mongoose.model("Academic", academicSchema);

// career model
const careerSchema = new mongoose.Schema({
  jobTitle: { type: String },
  company: { type: String }
});
const career = mongoose.model("Career", careerSchema);

填充查询:获取用户的学术和职业文档

const user = await User.find({ _id: requestedUserId })
  .populate("academic")
  .populate("career")
  .exec();

注意:requestedUserId 是要过滤的用户 ID。

【讨论】:

    【解决方案3】:

    这是我们可以使用给定查询 ID 查找用户的最简单查询

    router.get('/getInfoById/:id', async (req, res) => {
         const user = await User.aggregate([
               { $match: { _id: mongoose.Types.ObjectId(req.query.id) }},
               { $lookup: {
                  from: "career",
                  localField: "_id",
                  foreignField: "user",
                  as: "careers"
               }},
               { $lookup: {
                  from: "academic",
                  localField: "_id",
                  foreignField: "user",
                  as: "academics"
               }}
            ])
        res.send(user);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-04
      • 2020-06-27
      • 1970-01-01
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 2016-11-23
      相关资源
      最近更新 更多