Mongoose Get only size of a array - javascript

I'm using Mongoose and a MongoDB.
I have three schemas user and genres and songs.
const userSchema = new Schema({
name: String,
age: String,
favorite_genres: {
type: Schema.Types.ObjectId,
ref: 'Genre'
}
});
const genreSchema = new Schema({
name: String,
songs: {
type: Schema.Types.ObjectId,
ref: 'Song'
}
});
const songSchema = new Schema({
title: String,
artist: String,
length: String,
year: String
});
those are simplifid schemas, but they will do for this puprose.
So when I query a user I want to populate the doc with the favorite genres. But there (due to the potential amount of data) not with the ids of all songs, but only the number of songs. How can I achieve that?
I tried virtuals but they don't work the way I wanted it.
What I'm looking for is sth like the following:
const user = await User.findById(userID).populate({path: 'favorite_genres', select: 'name', sizeof: 'songs'}).lean()
// or
const user = await User.findById(userID).populate({path: 'favorite_genres', select: ['name', 'songs.length']}).lean()
Does anyone have an idea?

Related

How do I connect my mongoDB schema/models?

I'm new and trying to set up my noSQL DB model and am struggling. The intention is that "venues" can create events (tied to the venue), and "artists" can match-to and subsequently plan events. If you're an artist, you could also look at your dashboard and see the events you've played, so I need to connect Artists to Venues/events but don't know how.
Below is my Venue model. It works fine in my app, but where do I add Artists in?
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const VenueSchema = new Schema({
title: String,
image: String,
price: Number,
description: String,
location: String
});
module.exports = mongoose.model('Venue', VenueSchema);
Below is my Artist model. I haven't tested this one but I think it will work okay.
const mongoose = require('mongoose');
const { Schema } = mongoose;
const artistSchema = newSchema({
name: {
type: String,
required: [true, 'Artist must have a name']
},
genre: {
type: String
},
email: {
type: String,
required: [true, 'Contact email required']
},
})
Other than Artist and Venue, I'd like "events" to contain attributes "time" and "date". However, I have no idea where to fit events into the model.. How do I connect "events" between the two models?
I would design it like this
Venue schema (Same as yours): Where all the venues can be maintained independently of events and artists.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const VenueSchema = new Schema({
title: String,
image: String,
price: Number,
description: String,
location: String
});
module.exports = mongoose.model('Venue', VenueSchema);
Artist schema (same as yours): Where all the artists can be maintained independently of events and venues.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const artistSchema = newSchema({
name: {
type: String,
required: [true, 'Artist must have a name']
},
genre: {
type: String
},
email: {
type: String,
required: [true, 'Contact email required']
},
})
module.exports = mongoose.model('Artist', artistSchema);
Events schema: This is where artists and venue come together. Since there will be continuous operations on events (like updating progress) it can be done independently of artists and venues.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const eventSchema = new Schema({
venue_id: {
type: Schema.Types.ObjectId,
ref: 'Venue',
index: true
},
artist_id: {
type: Schema.Types.ObjectId,
ref: 'Artist',
index: true
},
created: {
type: Date, // Captures both date and time
default: Date.now
}
});
module.exports = mongoose.model('Event', eventSchema);

How to reach information already saved in other related models... MongoDB, NodeJS

I'm really new at this and I want to practice queries and tried to make a very different exercise but it didn't went as I expected.
I got three models:
const userSchema = new Schema({
info1: String,
info2: String,
},
const serviceSchema = new Schema(
{
name: String,
legalOwner: {
type: Schema.Types.ObjectId,
ref: 'User',
},
},
const orderSchema = new Schema(
{
client: { type: Schema.Types.ObjectId, ref: 'User' },
service: { type: Schema.Types.ObjectId, ref: 'Service' },
description: String
},
My users can behave like a legal owner or a client. I want to show the info that a user set as a LegalOwner, previously. And that is already saved in Mongo, How can I have access that data, is there a query for that? Do I need to set it in my model Order?
const orderSchema = new Schema(
{
client: { type: Schema.Types.ObjectId, ref: 'User' },
service: { type: Schema.Types.ObjectId, ref: 'Service' },
description: String,
legalOwner: { type: Schema.Types.ObjectId, ref: 'Service' },
},
I tried a lot of things on this query. But nothing works ...
await Order.findById(id).populate('service')
ObjectId are stored as _id within mongoDb as far as I am aware of.
Try this
const query = { _id: new ObjectID(id)};
await Order.findOne(query).populate('service')
Also import ObjectID from mongodb node_module as
import { ObjectID } from 'mongodb';

Mongoose populate and search by populated field

I am trying to do a simple search on a field that is a ref of another collection. Say I have the example collection of Invoices with a reference to a collection named client. So the example schema would look like so:
const invoiceSchema = new Schema({
name: {
type: String,
required: true
},
amount: {
type: Number,
required: true
},
client: {
type: Schema.Types.ObjectId,
ref: 'Client'
},
}
Then I have the client schema like so:
const clientSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
}
}
What I want to do is query the invoice schema and search for the name field in the client.
I have tried to use find and match with populate but that just returns the entire invoices collection and the client field is null on all of them:
const q = new RegExp(req.body.q, 'i');
invoices = await Invoice.find().populate({
path: 'client',
match: {
name: q
}
});
So how should I go about searching for a populated field with mongoose?

How to nest schemas in mongoose?

I'm trying to nest schemas using mongoose, but i got stuck and i don't really know why. Here is what i got.
My parent schema
const Comment = require("./Comment");
const BookSchema = new Schema({
_id: Number,
comments: [{ comment: Comment }],
ratings: [{ rate: Number }],
calculatedRating: Number
});
module.exports = Book = mongoose.model("book", BookSchema);
and child schema
const CommentSchema = new Schema(
{
userName: String,
rating: Number,
body: String,
submit_date: {
type: Date,
default: Date.now
}
},
{ _id: false }
);
module.exports = Comment = mongoose.model("comment", CommentSchema);
And with this setup im getting an error :
"TypeError: Invalid schema configuration: Model is not a valid type
at path comment."
I'm considering that i did something wrong with those exports but I'm not sure.
Your ./Comment should be:
const CommentSchema = new Schema(
{
userName: String,
rating: Number,
body: String,
submit_date: {
type: Date,
default: Date.now
}
},
{ _id: false }
);
module.exports = CommentSchema;
If you define as a new model as you did then it will create it's own collection and will be a new model instead of a sub document schema.

Annotate each object in MongoDB query

I have a Mongoose model with embedded documents:
const ticketSchema = new mongoose.Schema({
quantity: Number,
price: Number,
date: Date
});
const eventSchema = new mongoose.Schema({
name: String,
tickets: [ticketSchema]
});
const Event = mongoose.model('Event', eventSchema);
What I want is to extract all events with Event.find({}), but in each event, I want the date and price of the most recent ticket in the particular event, so I guess it's something like
Event.aggregate({ $groupBy: { $max: { tickets.date } });
Ii know this doesn't work, but I have to use some combination of find, aggregate, and $max.

Categories