I'm writing mongoose in Node.js, ES6.
I first specified a model called Address, and would like to use the Address model in the definition of another model, Channel.
The codes are like the following:
// Definition of Address
import mongoose from 'mongoose';
export const Address = mongoose.model('Address',
{
id: mongoose.SchemaTypes.ObjectId,
customer_id: String,
addresses: [{
address_type: String,
address_info: String,
}]
});
For another model Channel, I would like to have a subscriber field, which is a list of Address.
My tentative code is like the following:
import mongoose from 'mongoose';
import {Address} from './Address.js';
export const Channel = mongoose.model('Channel',
{
id: mongoose.SchemaTypes.ObjectId,
name: String,
path: String,
subscribers: [Address],
});
However, I got error like this:
TypeError: Invalid schema configuration: `model` is not a valid type within the array `subscribers`
I wonder how should I implement the idea in NodeJS?
If I got it right, you want each channel have an array of addresses specified to it. so you have to specify address field in your channel this way:
import mongoose from 'mongoose';
//import {Address} from './Address.js';
export const Channel = mongoose.model('Channel',
{
id: mongoose.Schema.Types.ObjectId,
name: String,
path: String,
subscribers: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Address'
}],
});
you do not need Address model imported into your Channel model, MongoDB will recognize it automatically. then when you want to create a channel document create it like this:
import {Address} from './Address';
import {Channel} from './Channel';
async function createChannel(){
Channel.create({
name: 'theName',
path: 'thePath',
subscribers: [await Address.find()] //you can add all addresses by just use find or use your specific query to find your favored addresses.
})
}
Related
In a function I have, I'm doing some stuff with the properties of an object of type CardType. Then, I want to be able to save those changes into my MongoDB database using the document.save() function. However, I have my code like this:
import { Types } from 'mongoose';
import Card from '../models/Card';
static async updatePriceForCardByID(cardID: Types.ObjectId) {
const card = await Card.findById(cardID).exec();
return updatePriceForCard(card!);
}
static async updatePriceForCard(card: CardType) {
// This function needs some properties of 'card', it only updates the price of the card
const newPrice = await StarCityController.getUpdatedPriceForCard(card.name, card.number);
card.prices.push(newPrice);
card.save(); // <-- Error appears here
return Card.findById(card._id).populate({ path: 'prices' }).exec();
}
and my CardType type like this:
import { Types } from 'mongoose';
export type CardType = {
_id: Types.ObjectId,
name: string,
prices: [Types.ObjectId],
number: string,
sku: string
}
the card.save() function is not working anymore like it was when my code was in JS. Now, I know that I'm passing a CardType as my parameter on my updatePriceForCard function, and as such, instead of a mongoose Document, I'm passing a variable of a type that doesn't have a save property in it.
My question is, what would be the best approach to tackle something like this?
You will have to add the mongoose Document type to your CardType.
import { Types, Document } from 'mongoose';
export type CardType = {
_id: Types.ObjectId,
name: string,
prices: [Types.ObjectId],
number: string,
sku: string
} & Document
This will add all the necessary document methods to the type. Make sure to import the Document type from mongoose, otherwise it may use the DOM-Document type which will not work.
Playground
So, I am just starting with Node/Mongo db and typescript, and I am kind of stuck in creating a Schema for this nested JSON Database. I have started something and, I would like to know if I am on the right track. So please if anyone would help me it would be great. Thanks in Advance
Data
[{
"a_class":[
{
"brand":"A-class",
"id":"1",
"year":"2015"
"price":"12665"
...
"engine_spec":{
...
}
...
}]
}
]
Interfaces
import { Document } from 'mongoose';
export default interface ICars extends Document {
a_class: BrandList[],
}
interface BrandList {
brand: string;
id:number;
year:number;
main_image: string;
price:number;
transmission:string;
fuel_type:string;
seating_capacity:number;
engine:number;
engine_specs:Specs;
volume_weights:Volume;
performance: Performance
images_interior: Interior
images_exterior: Exterior
}
interface Specs {
power:number;
power_per_litre:number;
torque:number;
fuel_system:number
}
interface Volume {
max_weights:number;
fuel_tank:number
}
interface Performance {
acceleration:number;
maximum_speed:number;
fuel_urban:number;
fuel_extra_urban:number
fuel_combined:number
}
interface Interior {
image_one:string;
image_two:string;
image_three:string;
image_four:string;
}
interface Exterior {
image_one:string;
image_two:string;
image_three:string;
image_four:string;
}
Schema
import mongoose, { Schema } from 'mongoose';
import ICars from '../interfaces/cars'
const CarsSchema: Schema = new Schema({
a_class:Array,
brand: String,
year:Number,
})
export default mongoose.model<ICars>('Cars', CarsSchema);
Get Route, So when I try to get all the data through postman, it is not allowing me, it is saying that the route is not being found 404. I have imported it to the server.js import carsRouter from './routes/cars'; router.use('./cars',carsRouter ), I don't know where the error could be
import express from 'express'
import Cars from '../models/cars'
const router = express();
router.get('/cars', (req:any, res:any )=>{
Cars.find()
.then(car=> res.json(car))
.catch(err => res.status(400).json(`Error: ${err}`))
})
export=router
According to mongoose document, we should avoid extending mongoose Document.
This approach works, but we recommend your document interface not
extend Document. Using extends Document makes it difficult for
Mongoose to infer which properties are present on query filters, lean
documents, and other cases.
We recommend your document interface contain the properties defined in
your schema and line up with what your documents look like in MongoDB.
Although you can add instance methods to your document interface, we
do not recommend doing so.
For more information, please reference: https://mongoosejs.com/docs/typescript.html#using-extends-document
And It seems that we can use mongoose sub documents for this requirement. For more information regarding the sub documents, please reference: https://mongoosejs.com/docs/subdocs.html#subdocuments
So in this case, we can rephrase your code a little bit:
Interfaces:
export default interface ICars {
a_class: BrandList[],
}
// The other interfaces can be kept
Schema:
const Exterior = new Schema({
// own fields
});
const Interior = new Schema({
// own fields
});
const Performance = new Schema({
// own fields
});
const Volume = new Schema({
// own fields
});
const SpecsSchema = new Schema({
// own fields
});
const BrandListSchema = new Schema({
// other fields
engine_specs: [SpecsSchema],
volume_weights: [VolumeSchema],
performance: [PerformanceSchema],
images_interior: [InteriorSchema],
images_exterior: [ExteriorSchema],
});
const CarsSchema: Schema = new Schema({
a_class: [BrandListSchema],
});
I'm currently working on a MERN Application. I'm fairly new to backend and database related topics.
I have configured this mongoose model, using the following schema:
item.model.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const itemSchema = new Schema({
title: String, // String is shorthand for {type: String}
author: String,
body: String,
date: { type: Date, default: Date.now },
meta: {
reports: {type: Number, default: 0}
}
});
const Item = mongoose.model('Item', itemSchema);
module.exports = Item;
In my api.js file, this is how I import the model:
const Item = require('../models/item.model');
Now, when starting my server I get following error:
TypeError: Invalid schema configuration: `String` is not a valid type at path `title`
I'm wondering why the type is invalid. I am using the syntax from the mongoose docs.
I did refactor my code and moved my backend folder. I can't imagine that this is related to the error, but since refactoring, this error appeared. I also tried moving the backend folder back where it was but I still get this error.
You can use another way for type definitions
title: 'String'
or
title: mongoose.Schema.Types.String
I'm implementing GraphQL with Mongoose.
In the typedef.js, I specified the Channel structure like this:
import { gql } from 'apollo-server-express';
export const Channel = gql`
type Channel {
"Name of the channel, this is the full path."
name: String!
parent: Channel
children: [Channel]!
}
`
It's clear that when I defining the model Channel, I also used it as the data structure of its elements.
And I would like to know how to write the model of it in mongoose.
What I'm writing now is like this:
//models/Channel.js
import mongoose from 'mongoose';
export const Channel = mongoose.model('Channel',
{
name: String,
parent: String,
children: [String]
});
Which I don't think is correct.
Note: I'm writing in ES6 of Javascript.
I defined a Model in a ts file.
I would like to use a specific mongoose connection (not the default one) with that model.
How can I associate my model to the connection ?
Excerpt form my TS file :
export interface iSuppliers extends mongoose.Document {
suppliers: string[];
fields: number[];
}
export const supplierSchema = new mongoose.Schema({
suppliers: {type:[String], required: true},
fields: [Number]})
.index({suppliers: 1}); // Additional index
export const supplier = mongoose.model<iSuppliers>('supplier', supplierSchema);
In my server.ts file :
import {supplier} from '....';
....
let database_2 = mongoose.createConnection(....);
Nothing happens when I use my supplier model to find data.
Obviously, I need to bind it to my database_2 connection ...
I am not sure about the way to that....
I found out my way...
I export a function that returns the model and use my connection as a parameter...
export function importedGameDatabase(mongooseConnection: mongoose.connection) { return mongooseConnection.model<iImportedGames>('importedGame', importedGamesSchema); }