Mongoose indexing sub-array compoent - mongodb

I'm trying to indexing one of my subarray component.
My mongoose schema is like that :
mongoose.Schema({
id: {
type: String,
default: uuidv4,
},
organization: {
type: String,
required: true,
},
names: [
{
name: {
type: String,
required: true,
},
language: {
type: String,
required: true,
enum: languages,
},
},
],
}
And If i create the index for organization like that :
schema.index({ organization: 'text' })
But what I want is to index the name inside the names array so I tried:
schema.index({ 'names.name': 'text' })
And here the index is not created, do you have an idea why ?

Related

How to develop nested condition query in mongoDB

I am pretty new to mongoDb and want to apply nested query.
I have a business schema like this:
const businessSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
businessType: {
type: Schema.Types.ObjectId,
ref: "businessCategory",
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
select: false,
},
review: {
type: [reviewSchema],
},
isDeleted: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
Business has a review where user can do the review and reviewSchema is
const reviewSchema = new mongoose.Schema(
{
user: {
type: Schema.Types.ObjectId,
ref: "users",
required: true,
},
rating: {
type: Number,
enum: [1, 2, 3, 4, 5],
},
reviewArray: {
type: [singleReviewSchema],
},
},
{ timestamps: true }
);
One user can do many reviews, and it has reviewArray.
ReviewArray schema is
const singleReviewSchema = new mongoose.Schema(
{
title: {
type: String,
},
description: {
type: String,
},
isDeleted: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
How to fetch the business with a condition business: isDeleted:false and its reviews with singleReviewSchema: isDeleted:false
I dont know your model names, so please replace path with correct names
but it might look like:
businnesModel.find({isDeleted: false})
.populate({
path: 'reviewModelName',
model: 'review',
populate: {
path: 'reviewArray',
model: 'singleReviewModelName',
match: {
isDeleted : false
}
}
})
It should provide you array of businessModel documents - even when their singleReviews array will be empty (because all of reviews are deleted, or there was zero reviews). So you have to filter it out in JS.
To avoid filtering in JS, and to do it a bit more efficient way for mongodb, you can go with aggregate instead.

Id is created for every nested objects in documents of a collection in mongodb via mongoose

I have a user schema. While saving document, for every nested object (quizHistory,record & responses) in document, mongoose add _id field automatically. For ref- quizHistory path
const userSchema = new Schema({
firstName: { type: String, required: true ,trim:true},
lastName:{ type: String, required: true ,trim:true},
email: { type: String, unique: true, required: true },
isUser: { type: Boolean, default: true },
password: String,
quizHistory: [{
quizId: { type: Schema.Types.ObjectId, ref: 'Quiz' },
record: [{
recordId:{ type: Number},
startTime: { type: Date },
responses: [{
quesId: { type: Schema.Types.ObjectId, ref: 'Question' },
answers: [Number]
}],
score: Number
}],
avgScore: Number
}]
})
Mongoose create virtual id by default(guide id).
Add this line to your schema.
_id : {id:false}

How to populate 2 ids in an object of an array Mongoose

I want to populate productId and distributor.
following is the array in my schema:
products: [
{
productId: {
type: String,
required: true,
ref: 'companyProduct'
},
quantity: {
type: String,
required: true,
},
distributor: {
type: String,
required: true,
ref: 'distributor'
}
}
],

Data is not inserted as per schema

I had defined mongoose schema and i tried to insert data into mongodb.But it is not inserted as per defined schema
export const EmpSchema: mongoose.Schema = new Schema({
name: {
type: String,
required: true
},
empNo: {
type: String,
required: true
},
skill: {
type: [String],
required: true
},
address: {
type: String,
required: true
}
}, {
_id: false,
versionKey: false,
retainKeyOrder: true
});
It is getting stored like Array elements as last field.like
name
empno
address
skill
export const EmpSchema: mongoose.Schema = new Schema({
name: {
type: String,
required: true
},
empNo: {
type: String,
required: true
},
skill: {
type: [String],
required: true
},
address: {
type: String,
required: true
}
}, {
_id: false,
versionKey: false,
retainKeyOrder: true
});
YOUR SCHEMA DEFINATION IS CORRECT PLEASE CHECK THE CONTROLLER PART WHERE YOU PUT THE INSERT QUERY . THERE MATTERS A INSERTION ORDER

Products with different variants schema

I am trying to create an e-commerce website using MongoDB. I have created a Product and variant model, my question is how can I search the product with variant, for example for "Size" user can add variant value as "S" or "Small". How can I search the product which has for example small product in this case as a product have many variants, how can I list eg. all products with small size. Here is my variant model.
var variantSchema = Schema({
name: {
type: String,
required: true,
unique: true
},
count: {type: Number, default : 0}
});
And my Product Schema is:
var productSchema = Schema({
sku: {
type: String,
lowercase: true
}, //, required: true, unique: true
name: {
type: String,
lowercase: true,
max: 65,
required: true
},
slug: {
type: String,
lowercase: true,
unique: true,
index: true,
slug: "name",
slug_padding_size: 3
},
status: Boolean,
listPrice: Number,
description: {
short: {
type: String,
trim: true,
lowercase: true
},
long: {
type: String,
trim: true,
lowercase: true
}
},
images: [],
categoryId: {
type: Schema.Types.ObjectId,
ref: 'Category'
},
userId: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
},
isActive: Boolean,
vars: [
{
varId : {
type: Schema.Types.ObjectId,
ref: 'Variants'
},
values: [
{
value : String,
image:[]
}
]
}
]
});
Based on your comment.
You can distinguish "Small" and "small" by ignoring case sensitive.
UserModel.findOne({
email: {'$regex': "^"+ email +"$", $options:'i'}
}, function (err, data) {
callback(err, data)
});
But you can not match S with Small.
Approach 1:
You need to maintain the possible words that you want to consider as Small. Maybe by inserting in Variant Schema an array ["S", "Small"] like this. But in this scenario. You must have to caution about S. S can be anything. (I am not recommended this approach)
Approach 2:
I would like to suggest making one schema (SizeSchema) that can present the size. for e.g. Small, Large, Extra small, Extra Large etc... And reference that SizeSchema to VariantSchema and ProductSchema to VariantSchema. (Triple relationship). And this would be fixed for the end user. No one will have an option like "S".
Hope this may help you.