Find the number of references from another model that match the items in the local array of references using Mongoose Virtual

Currently I am working with two models, namely Comment and Report.

const mongoose = require('mongoose');

const CommentSchema = new mongoose.Schema(
    {
        content: {
            type: String,
            trim: true,
            maxLength: 2048,
        },
        createdAt: {
            type: Date,
            default: Date.now,
        },
        parent: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Comment',
            required: false,
        },
        replies: [
            {
                type: mongoose.Schema.Types.ObjectId,
                ref: 'Comment',
            },
        ],
        isReply: {
            type: Boolean,
            default: false,
        },
    },
    { toJSON: { virtuals: true }, toObject: { virtuals: true } }
);

CommentSchema.virtual('reportCount', {
    ref: 'Report',
    localField: '_id',
    foreignField: 'comment',
    justOne: false,
    count: true,
});

CommentSchema.virtual('reportReplyCount', {
    ref: 'Report',
    localField: 'replies',
    foreignField: 'comment',
    justOne: false,
    count: true,
});

module.exports = mongoose.model('Comment', CommentSchema);

In the Comment model, there is a field named replies which is an array of references pointing to other comments. Users have the ability to report a comment, creating a new Report document in the collection with references to the comment and user. The Comment Schema includes two virtual properties, reportCount (displaying the number of reports for that comment) and reportReplyCount (showing the number of reports on comment replies). While the reportCount works as expected, the reportReplyCount does not function correctly. Instead of showing the number of reports, it displays the number of replies. Despite researching online, I could not find a similar issue.

const mongoose = require('mongoose');
    
    const ReportSchema = new mongoose.Schema({
        description: {
            type: String,
            trim: true,
            required: true,
            maxLength: 100,
        },
        reporter: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User',
            required: true,
        },
        createdAt: {
            type: Date,
            default: Date.now,
        },
        comment: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Comment',
            required: true,
        },
    });
    
    
    module.exports = mongoose.model('Report', ReportSchema);

Answer №1

After conducting thorough research, it appears that a suitable solution for your specific problem does not currently exist. While utilizing virtuals may be one approach to addressing the issue, there is a lack of guidance on implementing it in this particular context.

One potential workaround could involve creating a new virtual named reportReplyCount, which displays the number of reports associated with replies. By leveraging the aggregate function on the Comment model and substituting reportCount with the newly defined virtual, you can achieve the desired outcome:

CommentSchema.virtual('reportReplyCount', {
    ref: 'Report',
    localField: 'replies',
    foreignField: 'comment',
    justOne: false,
    count: true,
});

CommentSchema.methods = { ... }

CommentSchema.statics = { ... }

module.exports = mongoose.model('Comment', CommentSchema);

In cases where an alternate solution is feasible, it's advisable to explore those options rather than relying solely on virtuals.

A common practice among developers involves establishing a separate model to serve as the virtual entity. This entails constructing a schema similar to the original Report model but with modifications tailored for virtual functionality:

const mongoose = require('mongoose');

const ReportSchema = new mongoose.Schema({
    description: {
        type: String,
        trim: true,
        required: true,
        maxLength: 100,
    },
    reporter: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',
    }
});

module.exports = mongoose.model('Report', ReportSchema);

const VirtualReportSchema = new mongoose.Schema({ ... }, { _id : false });

module.exports = mongoose.model('VirtualReport', VirtualReportSchema);

To integrate the virtual into your existing schema, follow these steps:

CommentSchema.virtual('reportReplyCount', {
    ref: 'VirtualReport',
    localField: 'replies',
    foreignField: 'comment',
    justOne: false,
    count: true,
});

CommentSchema.methods = { ... }

CommentSchema.statics = { ... }

module.exports = mongoose.model('Comment', CommentSchema);

Remember to set the _id property within the virtual's definition to false to prevent any errors when accessing the virtual through dot notation. Failure to do so may result in unexpected issues during implementation.

Lastly, the discussion surrounding this topic originally surfaced on Stack Overflow at this thread. It is unfortunate that such queries are raised on platforms like Stack Overflow instead of being directed to MongoDB's official documentation, where comprehensive insights on virtuals are readily available.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Exploring the capabilities of NodeJs Buffer and handling C

Trying to utilize the Nodejs bluetooth-serial-port plugin along with Buffer to transmit "be\r\n" to my Bluetooth device. (It only works with this specific message) This Android tool here shows that it's functional. The issue arises when my ...

Add elements to an array of objects in Mongoose

My mongoose model has the following structure: var ModuleSchema = new Schema({ systems: [{ system: { type: Schema.ObjectId, ref: 'System' }, quantity: { type: Number } }] }) ...

Manipulating and managing nested documents with Mongoose CRUD operations

Hello, I am new to mongodb and looking for some guidance on the best practices to follow. Currently, I am working on setting up a simple blog using mongoose schemas like this: Blog Schema: const Blog = new Schema({ title : String, description : S ...

Error in Firebase cloud functions: The reference to the child is invalid. Please check the path provided as the first argument

I'm currently working on implementing push notifications by following this tutorial: https://www.youtube.com/watch?v=z27IroVNFLI Although the tutorial is a bit dated, there aren't many viable alternatives for Firebase web apps. When my cloud fu ...

Blending TypeScript declaration files and Node.js require across various files within an internal module

Is it problematic to mix Node.js modules (require) with TypeScript definition files (d.ts) multiple times within a module? In my case, I organize my modules into namespaces per folder similar to how it's done in C#. After compiling them all using tsc ...

What could be causing the issue of $.ajax being undefined while utilizing jQuery in Node.js?

I'm currently testing a module on Node.js that is meant for client-side use. In order to make $.ajax work, I need some guidance. To begin with, I have installed jQuery on the project using: $ npm install jQuery Despite this, when I try to access $. ...

Unsupported Media Type: Node.js does not support the content type application/octet-stream

Currently, I am utilizing koajs and the https://github.com/mscdex/busboy library to parse multipart files. Everything works seamlessly when using a normal multipart form upload. However, I recently attempted to upload a file using an ajax uploader. Upon dr ...

Node.js captures the Promise and provides detailed feedback

As I embark on my journey with Node.js + Express, currently in the process of structuring my HTTP APIs, I have a controller that utilizes a specific pattern: my_controller.js 'use strict'; var AppApiFactory = function (express, appService) { ...

Encountered a 'Topology is closed' error while using EJS

After creating my profile.ejs page, I encountered an error upon reloading the page. Can someone help me understand what's causing this issue? Below is all the code I've used. My setup includes Node.js and Express as the server technologies. I cam ...

What is the best way to define the goal path for a Maven project during development?

I've been attempting to set up node and npm in a specific location, but the default path is directing to "C:/Users.../webapp/node/node.exe" and there's no node directory present. I'm looking for a solution to modify the path so that I can in ...

encountered difficulty in fetching information from mongoDB

I have successfully created user accounts and stored them in a MongoDB users database within a users collection. To validate that the users are indeed stored, I am utilizing Studio 3T. Within my dal.js file, I have implemented the code responsible for retr ...

When using Mongoose paginate, there is always one missing document

I currently have a database with 6 documents and the following route: router.get('', async (req, res) => { const search = req.query.search !=null ? req.query.search : ""; const page = req.query.page !=null ? req.query.page : 1; const limit = ...

A function injected into a constructor of a class causes an undefined error

As I delve into learning about utilizing typescript for constructing API's, I have encountered a couple of challenges at the moment. Initially, I have developed a fairly straightforward PostController Class that has the ability to accept a use-case wh ...

Pass a shell environment variable as an argument when executing an npm script

Is there a way to successfully pass environment variables as arguments to npm scripts? export ENVIRONMENT=test.proxy.json npm run test I'm attempting to achieve something similar in my package.json file: npm run test --proxy-config-file $ENVIRONMEN ...

"Is it possible to generate a Keystone list object without the need for an

Can a Keystone List (Model) item be created without the initial dialog? I am looking to create the item directly on the detail page, with required fields like Files and TextArray that would not function properly in a dialog. I have attempted to set init ...

How can we rewrite a rule while disregarding the initial directory section?

I've spent 2 hours trying to figure this out, but I just can't seem to find the solution online. Here is the Rewrite-Rule in my .htaccess file: RewriteCond %{REQUEST_URI} ^/blog(.*) RewriteRule ^(.*) http://localhost:2368/$1 [P] My goal is to ...

Can you explain the concept of an "include template" in the Express/Jade framework?

This informative source mentions the existence of include templates. Despite several searches, I couldn't locate specific documentation on them. Can you explain what they are? ...

Understanding package.json dependencies in Node.js is crucial for managing a project's external dependencies

Within my node project, I organize independent modules into folders with main.js as the entry point and helpers for each module located in separate files within the same folder. Ex: Aggregator: |___package.json |___main.js |___node_modules ...

The node.js and express.js update operation (CRUD) is not rendering the CSS files properly

I am currently developing a CRUD app using Node.js/Express.js with EJS as the templating engine. The concept I'm working on involves displaying user_ids from a database, and when an admin clicks on a user_id, it should redirect them to the edit_team. ...

The files fail to respond after executing npm and initiating npm starts

I'm completely new to AngularJS. When I run npm start, the server status shows "serving from :. /" but it doesn't seem to pick up the file even though I've specified the file name as index.html. Can someone please assist me in resolving this ...