How to paginate array of key values using mongoosePaginate? - node.js

I created Category Schema where there is Array of Products I want to paginate items of array not category it self, How can I fix this issue???
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const mongoosePaginate = require('mongoose-paginate-v2');
const categorySchema = new Schema({
category: {
type: String,
required: true,
}
items:[{
title: {
type: String,
required: true,
},
price: {
type: String,
required: true,
},
}]
});
categorySchema.plugin(mongoosePaginate);
const Category = mongoose.model('Category', categorySchema);
module.exports = Category;
if I do it like this it wont work it says "category.items.paginate is not a function"
let category = await Product.findOne({ category: mycategory })
let categoryItemsPagenateResult = category.items.paginate()

for this situation you don't need to any plugin, just use $slice like this:
let skip = 0
let limit = 3;
let x = await Product.findOne({ category: mycategory }).select({ 'items': { '$slice': [skip,limit] } }).lean()
in x.items you have result

Related

Mongoose fetch data from collection A if it's reference exists on collection B

I need your help please with a mongoose query for my express app.
I have 3 collections Movies, TvShows and Trailers and I need to fetch all movies or shows that have trailers.
here are the models:
var TrailerSchema = new Schema(
{
link: {
type: String,
required: true,
},
movieId: { type: mongoose.Schema.Types.ObjectId, ref: 'Movie' },
showId: { type: mongoose.Schema.Types.ObjectId, ref: 'Show' },
}
)
module.exports = mongoose.model('Trailer', trailerSchema)
const mongoose = require('mongoose')
const Schema = mongoose.Schema
var movieSchema = new Schema(
{
title: {
type: String,
required: true,
},
rating: {
type: Number,
},
}
)
module.exports = mongoose.model('Movie', movieSchema)
in the Trailer collection there are some documents with the movieId field and some with showId.
Now how can I fetch all the movies or shows that have trailers?
because you just stored movieId in TrailerSchema and movieSchema don't have field like TrailerId:[{type: mongoose.Schema.Types.ObjectId, ref: 'Trailer'}], can not use populate...
but for your issue at first
let listOfIds = await Link.find( { movieId: { $exists: true } }, 'movieId._id' ).lean()
I don't know real data stored in Trailer collection for query in Trailer.find after get IDs you should search in Movie collection to get all info
let listOfMovies = await Movie.find({ _id: { $in: listOfIds.map((id) => {if(id.movieId) return id.movieId._id} ) }, })

How to add item to mongoose Array

I'm developing a web app that uses mongodb database using mongoose in node.js...
Now, I'm trying to build the rate feature, in this feature, people can rate the store and give some comments about that store.
This is the structure:
rate: {
author: req.body.author,
text: req.body.text
}
To update it I'm using the "findOneAndUpdate" function, but, Always when i do it, the existent rate is overwritten by the new... Can you guys help me?
Here you can do. I am just demonstrating with example
Model
//Model
const ratingSchema = new mongoose.Schema({
author: { type: String, required: true },
text: { type: String, required: true }
});
const productSchema = new mongoose.Schema({
name: { type: String, required: true },
description: { type: String },
rating: [ratingSchema],
price: { type: Number, default: 1 },
});
module.exports = mongoose.model('Product', productSchema );
Now you can just push a new array
Controller
const ProductModel = require('./models/product');
const { id } = req.params;
const { author, text } = req.body;
PersonModel.update(
{ _id: id },
{ $push: { rating: { author, text }} },
done
);
More about: https://mongoosejs.com/docs/api/array.html#mongoosearray_MongooseArray-push
Try this one
The model
const schema = new mongoose.Schema({
name: String,
description: String,
price: Number,
rating: [{
author : String,
text : String
}]
});
module.exports = mongoose.model('Product', schema );
In request handler
const Product = require('./models/product');
const { id } = req.params; //product ID
const { author, text } = req.body;
const product = Product.findById(id);
product.rating = [...product.rating,{ author, text }]
product.save();
One way is with regular JS, you can simply store the document you want to update in a variable. Then, use the push method on the rate field before calling save on the variable.

How to populate without _id in mongoose with array of foreign key?

I know I can use virtual in mongoose to populate without _id.
But My situation is something like this:
const storeSchema = new mongoose.Schema({
store_id: Number,
store_name: String,
cart_tokens: [String],
})
const cartSchema = new mongoose.Schema({
cart_token: String,
items: { type: Array },
})
My cart_tokens in the store schema is an array instead of one value.
I want the result of store be something like:
{
store_id: xxx,
store_name: xxx,
carts:[
{
cart_token: xxx,
items: [...],
},
{...},
{...}
]
}
Is it possible to do this?
This will work:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
let cartSchema = new Schema({
cart_token: String,
items: { type: Array },
})
let storeSchema = new Schema({
store_id: Number,
store_name: String,
cart_tokens: [cartSchema]
});
module.exports = mongoose.model('Cart', cartSchema);

How to perform inner join in mongoose

I was googling for last two days but no success. I need to perform inner join in mongoose with two schema but not getting response my other collection.
My question is what am I missing in my code? Please help me with this.
I want to get result of class and subjects also.
exports.classSubjectList = async (req, res, next) => {
const obj = await ClassSubject.find().populate('classmodel').exec();
res.status(200).json({
success: true,
response: obj
});
};
//ClassSubjectModel
const mongoose = require('mongoose');
mongoose.Promise = global.Promise
const Schema = mongoose.Schema
const classModel = require('../class/classModel');
const subjectModel = require('../subject/subjectModel');
var classsubject = new Schema({
ClassId: String,
SubjectId : String,
IsShow: { type: Boolean, default : true},
classmodel: { type: mongoose.Schema.Types.ObjectId, ref: classModel },
subjectmodel: { type: mongoose.Schema.Types.ObjectId, ref: subjectModel },
});
//Class Model
const mongoose = require('mongoose');
mongoose.Promise = global.Promise
const Schema = mongoose.Schema
var classinfo = new Schema({
ClassName: String,
IsShow: { type: Boolean, default : true},
});
module.exports = mongoose.model('classinfo', classinfo);
//SUBJECT Model
const mongoose = require('mongoose');
mongoose.Promise = global.Promise
const Schema = mongoose.Schema
var subject = new Schema({
SubjectName: String,
IsShow: Boolean,
});
module.exports = mongoose.model('subject', subject);
result
[
{
"IsShow": true,
"_id": "5e1efc0f354849246c472cfe",
"SubjectId": "5e1da60bf52acb30b87e92c4",
"ClassId": "5e1ec13ed777bf28d01e2481",
"__v": 0
}]
You should define ref as the name of your schema & not the object reference
Do it like this
classmodel: { type: mongoose.Schema.Types.ObjectId, ref: 'classinfo' }
subjectmodel: { type: mongoose.Schema.Types.ObjectId, ref: 'subject' },
// here 'classinfo' & 'subject' are the names you defined your schema with
You should populate both if you want a proper inner join
const obj = await ClassSubject.find().populate('classmodel').populate('subject').exec();
You must store ids of class & reference in classmodel & subjectmodel
key of your document for this to work
Hope this helps

Mongoose populate returning data without population

I know that this question was asked many many times but i still can't find a solution
So this is my db
Product :
Ingredient :
Schemas :
ingredient.js
const mongoose = require("mongoose");
var IngredientSchema = new mongoose.Schema({
quantity: {
value: Number,
unit: String
},
comment: String,
product: { type: mongoose.Schema.Types.ObjectId, ref: "Product" }
});
module.exports = mongoose.model("IngredientSchema", IngredientSchema);
product.js
const mongoose = require("mongoose");
var ProductSchema = new mongoose.Schema({
name: {
type: String,
default: "",
trim: true,
required: "Name cannot be blank"
},
category: {
type: String,
default: "",
trim: true
},
convertion: [
{
unit_from: String,
unit_to: String,
value_from: Number,
value_to: Number
}
],
default_unit: String
});
const Product = (module.exports = mongoose.model(
"ProductSchema",
ProductSchema
));
this is the populate function :
ingredientRoutes.route("/:id").get(function(req, res) {
let id = req.params.id;
Ingredient.findById(id)
.populate("produit")
.exec()
.then(function(data) {
console.log(data.product, "***");
})
.catch(function(err) {
console.log(err);
});
});
this is the result that i'm getting :
just the id of the product without making the population
Any idea ?

Resources