首页 > 解决方案 > Mongoose 通过引用字段查找

问题描述

我有一个这样的频道模式:

const channelSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      unique: true
    }
  }
);

这是反馈模式:

const feedbackSchema = new mongoose.Schema({
  channelId: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "channel",
    require: true
  }
});

如何按频道名称查找反馈?

Feedback.find({channelId.name : 'something'})

谢谢

标签: node.jsmongoose

解决方案


由于您没有从通道架构到反馈架构的任何引用,因此您可以使用mongoose的填充虚拟功能。

所需的更改如下所示:

1-) 像这样替换您的频道模式以使用虚拟填充:

const mongoose = require("mongoose");

const channelSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      unique: true
    }
  },
  {
    toJSON: { virtuals: true }
  }
);

// Virtual populate
channelSchema.virtual("feedbacks", {
  ref: "feedback",
  foreignField: "channelId",
  localField: "_id"
});

module.exports = mongoose.model("channel", channelSchema);

2-) 使用以下查询查找给定频道名称的反馈:

请注意,我在查询中对通道名称进行了硬编码,您可以从请求正文或请求查询或请求参数中读取它。

router.get("/feedback", async (req, res) => {
  const result = await Channel.findOne({ name: "Channel 1" }).populate({
    path: "feedbacks"
  });

  res.send(result);
});

响应将是这样的:

[
  {
    "_id": "5de5509476a9c34048c1d23d",
    "name": "Channel 1",
    "__v": 0,
    "feedbacks": [
      {
        "_id": "5de5512d7d87de2d4c6b38d2",
        "channelId": "5de5509476a9c34048c1d23d",
        "__v": 0
      },
      {
        "_id": "5de551357d87de2d4c6b38d3",
        "channelId": "5de5509476a9c34048c1d23d",
        "__v": 0
      }
    ],
    "id": "5de5509476a9c34048c1d23d"
  }
]

或者,如果您只对反馈感兴趣,您可以通过以下方式访问它们result.feedbacks

router.get("/feedback", async (req, res) => {
  const result = await Channel.findOne({ name: "Channel 1" }).populate({
    path: "feedbacks"
  });

  res.send(result.feedbacks);
});

这将为您提供一系列反馈,如下所示:

[
    {
        "_id": "5de5512d7d87de2d4c6b38d2",
        "channelId": "5de5509476a9c34048c1d23d",
        "__v": 0
    },
    {
        "_id": "5de551357d87de2d4c6b38d3",
        "channelId": "5de5509476a9c34048c1d23d",
        "__v": 0
    }
]

推荐阅读