'Querying Views with Mongoose (and encapsulating documents fields)

I use mongodb views to encapsulate data in a Data Transfer Object.

After the first run of the code below the view is created in the database. Subsequent execution of my code will result in the error: MongoError: Namespace already exists. I find this method rather awkward.

There is not much information in google how to use views in mongoose. So can you share some of the best practices of encapsulating data for a client? Maybe I shouldn't use mongodb views for this purpose. What do you recommend?

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    first: String,
    last: String, 
});
const viewSchema = new mongoose.Schema({
    first: String,
    last: String, 
});

const User = mongoose.model('User', userSchema);

(async () => {
    mongoose.connect('mongodb://localhost:27017/tests');

    await User.create([{first: '1', last: '2'}, {first: '1', last: '2'}]);

    //creates 'UserView' view every run of the code :(
    await mongoose.connection.db.createCollection('UserView', {
        viewOn: 'users',
        pipeline: [
            { $project: { first : 0,} }
        ]
    });
    
    const View = await mongoose.model('View', viewSchema, 'UserView')
    console.log(await View.findOne());
    mongoose.disconnect();
})();


Solution 1:[1]

I had the same requirement and this is the solution I came up with after a little bit of research:

mongoose
    .connect(process.env.DB_CONNECTION)
    .then(() => {
        const mongooseConnection = mongoose.connection;
        const blocksAndMutesCollectionName = "blocks_and_mutes";
        mongooseConnection.db
            .listCollections({
                name: blocksAndMutesCollectionName
            })
            .next((error, result) => {
                // `result` null if collection not found
                if (!result) {
                    mongooseConnection.createCollection(blocksAndMutesCollectionName, {
                        viewOn: "users",
                        pipeline: require("./db/pipelines/blocks-and-mutes"),
                        collation: {
                            locale: "en",
                            strength: 2
                        }
                    });
                }
            });
        console.log("Connected to the database");
    })
    .catch(() => {
        console.log("Unable to connect to the database");
    });

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mr. X