【问题标题】:cross collection query in mongoose with $lookup使用 $lookup 在 mongoose 中进行交叉集合查询
【发布时间】:2019-02-25 11:13:34
【问题描述】:

我正在建立一个问答数据库。我有三个模式,用户、问题和回复(答案)。我的问题从我想查询用户尚未回答的问题开始。但是当我运行这个查询时,我得到一个空回复数组的问题。我应该以某种方式填充它吗?这是我得到的:

查询:

let getQuestions = (req, res)=>{

    Question.aggregate([
        {
            $match: {isGlobal: true}
        },
        {
            $lookup: {
                from: 'Reply',
                localField: '_id',
                foreignField: 'questionID',
                as: 'replies'
            }
        },
        // {
        //     $match: {}
        // }
    ]).then(foundQuestions=> console.log(foundQuestions))
};

用户架构(简化):

const mongoose = require('mongoose');

const userSchema = mongoose.Schema({
    firstName: String,
    lastName: String,
    email: String,
    questionReplies: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Reply'
        }
    ],
}, {timestamps: true});

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

问题架构:

const mongoose = require('mongoose');

const questionSchema = mongoose.Schema({
    title: String,
    description: String,
    isGlobal: Boolean,
    options: [
        {
            number: Number,
            title: String,
        }
    ]
}, {timestamps: true});

module.exports = mongoose.model('Question', questionSchema);

回复架构:

const mongoose = require('mongoose');

const replySchema = mongoose.Schema({
    questionID: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Question',
        required: true
    },
    email: {type: String, required: true},
    answerID: {type: String, required: true},
    number: Number,
    title: String,
}, {timestamps: true});

module.exports = mongoose.model('Reply', replySchema);

我的回复集合里面有这个文档:

"questionID" : ObjectId("5c6f6867cbff9c2a9004eb6d")

我对此 ID 有疑问:

"_id" : ObjectId("5c6f6867cbff9c2a9004eb6d"),

(也欢迎任何关于改进数据库设计的意见)。

【问题讨论】:

    标签: mongodb mongoose


    【解决方案1】:

    试试下面:

    let getQuestions = (req, res)=>{
        Question.aggregate([
            {
                $match: {isGlobal: true}
            },
            {
                $lookup: {
                    from: 'Reply',
                    localField: '_id',
                    foreignField: 'questionID',
                    as: 'replies'
                }
            },
            {
                 $match: { "replies": { $eq: [] } }
            }
        ]).then(foundQuestions=> console.log(foundQuestions))
    };
    

    所以你会得到没有任何回复的问题。

    【讨论】:

    • 我也认为这应该可行,但在最后一个 $match 之前,$lookup 返回一个空的回复数组。我认为最后一场比赛对它没有任何作用。但我会试一试。
    • 您收到的问题回复数组为空,这意味着尚未有任何用户回答此类问题。我想这就是您在上面所说的“我只想查询用户尚未回答的问题”的您想要的结果。
    • 但是这个问题有回复,这就是问题所在。 $lookup 应该返回包含回复的问题,然后最后一个$match 将选择没有回复的问题。但是我的回复数组是空的,即使现在我的数据库中有这个问题的回复。
    【解决方案2】:

    我解决了我的问题,并在这里发布以供将来参考。

    $lookup中使用的from字段是指mongodb创建的collection name,而不是mongoose中使用的Model name。所以正确的查询是:

    $lookup: {
        from: 'replies',
        localField: '_id',
        foreignField: 'questionID',
        as: 'replies'
    }
    

    然后我添加了

    {
        $match: { "replies": { $eq: [] } }
    }
    

    只找到没有答案的问题。

    【讨论】:

      猜你喜欢
      • 2017-02-16
      • 2020-05-19
      • 1970-01-01
      • 2021-09-23
      • 2019-10-01
      • 2019-01-21
      • 1970-01-01
      • 1970-01-01
      • 2013-09-04
      相关资源
      最近更新 更多