Mongoose populate nested element inside of multiple arrays - javascript

I have the following schema:
const userSchema = new Schema({
...,
categories: [
{
name: {
type: String,
required: true
},
products: [
{
type: mongoose.Types.ObjectId,
required: false,
ref: 'Product'
}
]
}
],
...
}
I want to get all the products a user have.
I have seen more questions about this topic but I don't get it to work.

If you entered your data correctly you can do like this:
let result = await User.findById(id).populate("categories.products").lean()

Related

Pushing object to triple nested array in Mongoose

I am trying to figure out how to access and push an object into a triple nested array while using mongoose.
My idea is to divide a blog post into an array of chapters, where each has their own array of pages. Each page will have a title, image and body.
Story schema (parent document)
const mongoose = require('mongoose')
const pageSchema = require('./pageModel')
const storySchema = mongoose.Schema({
storyTitle: {
type: String,
required: [true, 'Title required.']
},
storyAuthor: {
type: String,
required: [true, 'Author required.']
},
storyImage: {
type: String,
required: true,
},
chapters: [{
chapterTitle: {
type: String,
//required: [true, 'Title required.']
},
chapterSummary: {
type: String,
// required: [true, 'Summary required.']
},
pages: [pageSchema]
}]
})
module.exports = mongoose.model('Story', storySchema)
the Page Schema
const mongoose = require('mongoose')
const pageSchema = mongoose.Schema({
pageTitle: {
type: String,
required: [true, 'Title required.']
},
pageBody: {
type: String,
},
pageImage: {
type: String,
}
})
module.exports = pageSchema;
Simple ops
const mongoose = require('mongoose')
const Story = require('./storyModel')
const Page = require('./pageModel')
const test = new Story({
storyTitle: 'Test',
storyAuthor: 'Myself',
storyImage: 'test',
});
console.log(test);
test.chapters.push({
chapterTitle: 'chapter 1',
chapterSummary: 'let us see',
})
const first = {
pageTitle: 'A page',
pageImage: 'image',
pageBody: 'A body'
}
console.log(test)
//test.chapters[0].pages[0].push(page)
test.chapters[0].pages.push(first)
console.log(test)
When I log each step, the parent is correctly made, and I am able to append a chapter to the chapters array. But when I the first object, the change isn't visible.
If I log test.chapters, the pages array shows pages: [ [Object] ]
And if I log test.chapters.pages, I just see 'undefined'.
Any suggestions and critique is appreciated.

Mongoose text index on array of subdocuments always returns nothing

I have a collection of documents for users to track companies that looks like this:
const mongoose = require("mongoose");
const TrackingListSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "users",
required: true,
index: true
},
email: {
type: String,
required: true,
},
companies: [{
country: {
type: String,
required: true
},
countryCode: {
type: String,
required: true
},
name: {
type: String,
required: true
}
}]
});
TrackingListSchema.index({"companies.name": "text"});
module.exports = mongoose.model("trackinglist", TrackingListSchema);
As you can see, I am creating a text index on the "companies.name" field.
However, when I run a query as such:
TrackingList.aggregate([
{$match: {
"companies.countryCode": "us",
$text: {
$search: "Some Company",
$caseSensitive: false
}
}},
{$project: {
_id: 0,
email: 1,
}}
])
Nothing is returned even though I am sure that at least one tracking list has a company with that name. What am I doing wrong? Am I creating the text index wrong because it is inside an array? I thought I had this working but now I just can't get it to work.

How to query a mongo document using mongoose?

MongoDB documents contain an array of objects and what is the best way to query those documents if I want to find and remove an object from an array with some specific value;
Here is an example of the document schema
const mongoose = require("mongoose");
const LibrarySchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
},
books: [
{
type: new mongoose.Schema({
bookName: {
type: String,
required: true,
},
chapterReading: {
type: Number,
default: 1,
required: true,
},
}),
},
],
});
const Library = mongoose.model("Library", LibrarySchema);
exports.Library = Library;
If I want to find and remove a book with some bookName
Use $pull
Example :
Library.update({}, { $pull: { books: { bookName: "Yourbookname" } } })

Foreign key composed from multiple models

I am using mongo and mongoose and I am trying to model my app.
I have the following models: ProductA, ProductB and ProductChat.
Each Product can have many Chats. Each chat is related to one and only product (A or B).
I'd like ProductChat to have a reference to the relevant product document. I thought about adding productType, productId fields to ProductChat:
const ProductChatSchema = new Schema({
...
...
productType: {
type: 'String',
required: true,
enum: [ 'A', 'B' ]
},
product: {
type: Schema.Types.ObjectId,
required: true,
ref: '???' // Ref to what?
},
...
...
});
But I don't know what to put on 'ref'...
I'd like to avoid adding productAId, productBId fields on ProductChat because there might be many products.
Any idea how to do it correct?
As there are many products, give ProductChat ref to ProductsA(B, C..) collection in an array.
const productA = new Schema({
ProductChatIds: [{
type: Schema.Types.ObjectId,
ref: 'ProductChat'
}]
});
const productB = new Schema({
ProductChatIds: [{
type: Schema.Types.ObjectId,
ref: 'ProductChat'
}]
});
ref field means in which collection the id mentioned is gonna be searched for. So, you have to refer to the collection.
For example:
var postSchema = new Schema({
name: String,
postedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
dateCreated: Date,
comments: [{body:"string", by: mongoose.Schema.Types.ObjectId}],
});
Then make your model:
var Post = mongoose.model('Post', postSchema);

Storing Javascript Array of Objects in Mongo DB using Mongoose

I have an array of the form [{key: ..., type: ..., value: ...}] and want to store it in the fields field in the following schema:
var articleSchema = mongoose.Schema({
name: {
type: String,
unique: true,
required: true
},
updated: {
type: Date,
default: Date.now
},
pageviews: {
type: Number,
default: 0
},
fields: [{
key: String,
type: String,
value: String
}],
image: String
});
I am doing this as follows, my Javascript array referenced as keyValueObj
Article.findOneAndUpdate(
{ name: articleName },
{
fields: keyValueObj
},
{ upsert: true },
callback
);
However, all that is stored in the database in the fields field is an array of strings like this: ["[object Object]"]
How can I store my Javascript array so that it matches my mongoose schema correctly?
I was able to fix this using Molda's idea of using a separate schema.
The updated fields field in the articleSchema now looks like this:
fields: [{
type: Schema.Types.ObjectId,
ref: 'Field'
}]
I then converted the array to an array of schema objects, like this:
keyValueObj = keyValueObj.map(function(fieldObj){
return new Field({
key: fieldObj.key,
type: fieldObj.type,
value: fieldObj.value
});
});
I was then able to store keyValueObj the was doing it in the initial code.

Categories

Resources