skip to Main Content

I have the below Post schema. The post schema contains an array field that may contain other posts as replies. What I would like to do is retrieve all documents which are not referenced in any post’s replies field. Basically get all posts that are not replies of an original post.

const mongoose = require('mongoose');

const schema = new mongoose.Schema({
    creator: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        validate: [mongoose.Types.ObjectId.isValid, 'Creator ID is invalid']
    },
    owner: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
        validate: [mongoose.Types.ObjectId.isValid, 'Owner ID is invalid']
    },
    content: {
        type: String,
        required: 'Content is required'
    },
    likes: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Like',
            validate: [mongoose.Types.ObjectId.isValid, 'Like ID is invalid']
        }
    ],
    replies: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Post'
        }
    ]
}, {
    autoCreate: true,
    timestamps: true
});

const Post = mongoose.model('Post', schema);

module.exports = Post;

I have tried using $lookup with $match & $nin but I cannot make it work properly. Any help would be greatly appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    IF I'm not mistaken this seems to work:

                let posts = await MODELS.Post.aggregate([
                    {
                        $lookup: {
                            from: 'posts',
                            localField: '_id',
                            foreignField: 'replies',
                            as: 'references'
                        }
                    },
                    {
                        '$match': {
                            'references._id': {
                                '$exists': false
                            }
                        }
                    },
                    {
                        '$sort': {
                            createdAt: -1
                        }
                    },
                    {
                        '$project': { 
                            references: false
                        }
                    },
                    {
                        '$limit': 10
                    }
                ]);
    

  2. I think it’d be easier to just update the schema to track either a) whether it’s an original post or b) whether it’s a reply. Then you can just do a query by that Boolean field rather than looping through a series of arrays.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search