I have MongoDb as my db . data in this instance is populated on a daily basis through a csv file import.
a document in this collection/csv looks as
{
"_id": {
"$oid": "611e455ddd7c222661065037"
},
"country": "India",
"country_code": 91,
"country_iso": "IND",
"origination_prefix": "",
"voice_rate_in_usd": 0.3148,
"voice_unit_in_seconds": 60
}
This data is fetched via node.js api as below
//some code emitted for brevity
import { connect, Schema, model } from "mongoose";
import express from "express";
const router = express.Router();
const schema = new Schema<Pricing>({
country: { type: String, required: true },
countryCode: { type: String, required: false },
countryIso: { type: String, required: true },
destinationPrefix: { type: [Number] },
voiceRate: { type: Number },
voiceUnit: { type: Number },
});
const pricesModel = model<Pricing>("call_rate", schema);
router.get("", async (req, res) => {
const prices = await pricesModel.find().limit(10);
res.send(prices);
});
export default router;
Being a newbie to node.js on googling I get a number of packages
https://www.npmjs.com/package/typescript-json-object-mapper
https://www.npmjs.com/package/object-mapper
https://www.npmjs.com/package/serialize-ts
now I am not sure which is the most common/popular/recommended package & how do I use it
How can I map my DB object to the app object?
Thanks!
Since you are using MongoDB and Mongoose, you don't have to do anything. Mongoose will automatically return objects or array of objects for each query.
Related
I'm trying to create a one to many relationship between Category and Services models.
I have two schemas: Category and Service.
Category schema holds services array.
Service schema hold category _id.
I'm trying to retrieve all Categories including services.
Category schema:
import mongoose from 'mongoose';
const categoriesModel = new mongoose.Schema(
{
category: {
type: String,
required: true,
},
services: [{ type: mongoose.SchemaTypes.ObjectId, ref: 'Service' }],
},
{ timestamps: true }
);
export const Category = mongoose.model('Category', categoriesModel);
Service schema:
import mongoose from 'mongoose';
const serviceSchema = new mongoose.Schema(
{
serviceName: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
images: {
type: Array,
image: Buffer,
required: true,
},
category: {
type: mongoose.SchemaTypes.ObjectId,
ref: 'Category',
required: true,
},
},
{ timestamps: true }
);
export const Service = mongoose.model('Service', serviceSchema);
HTTP get request to retrieve all Categories including Services:
export const getAllCategories = async (req, res) => {
try {
const docs = await Category.find({}).populate({
path: 'services',
model: 'Service',
});
console.log(docs);
res.status(200).json({ data: docs });
} catch (err) {
res.status(400).json(err.message);
}
};
This is what I get as a response from the request above:
{
"services": [],
"_id": "60affe06c71901281d3d820d",
"category": "Electricity"
},
I've tried different ways to populate services but none of them worked.
What I've tried so far:
Add additional nesting to services attribute.
Adding object to the populate params:
{
path: 'services',
model: 'Service',
}
Removing existing data ant posting additional one.
Fun fact. Retrieving each Service individually, service data includes the actual category, that it's been assigned to:
export const getAllServices = async (req, res) => {
try {
const doc = await Service.find({}).populate('category');
res.status(200).json({ data: doc });
} catch (err) {
res.status(400).json(err);
}
};
Is there something I'm missing regarding including services within retrieving categories? It's really interesting, because somehow the actual services data is [].
EDIT: Each category in Categories collection has empty services array. The services are added dynamically, they might be null for specific category until user adds a service and assigns a category to it. Is this forbidden? Do I need to find specific category and add a specific service to category while creating new service? If yes, this would require to add additional Category model to the services.controller.js and find the category. Is this really an appropriate solution?
I am using mongoose and express to access data within MongoDB and I can see the JSON when I make a reference to the database, but when I try to target an object nested inside, I get an undefined message.
JS file to access DB.
const express = require('express');
const router = express.Router();
const skate_tricks = require('../models/SkateTrick');
router.get('/', (req, res) => {
skate_tricks.find({}, (err, result) => {
if (err) {
res.send(err);
} else {
res.send(result);
}
});
});
module.exports = router;
Results snippet using Postman
[
{
"trick_type": [],
"_id": "5f34a5782e0d2fe1c2847633",
"tricks": [
{
"trick_id": 0,
"trick_name": "ollie",
"trick_type": [
"flat"
],
"trick_difficulty": "n",
"trick_description": "Fundamental trick involving jumping with the skateboard. Performed by popping the tail with the back foot and sliding the front foot up towards the nose of the board. The sliding action levels the board while you are airborn."
}
]
}
]
I want to access the "tricks" array of objects directly, but it's not working.
res.send(result.tricks);
Try to add tricks to your mongoose model
const mongoose = require("mongoose");
const SkateTrickSchema = new mongoose.Schema({
trick_id: { type: Number, required: true, unique: true },
trick_name: { type: String, unique: true },
trick_type: { type: Array, required: true },
trick_difficulty: { type: String, required: false },
trick_description: { type: String, required: false },
tricks: { type: Array, required: true }
});
module.exports = SkateTrick = mongoose.model(
"skateboard-tricks",
SkateTrickSchema
);
One thing what you can try is to add .lean() to your query
router.get("/", async (req, res) => {
try {
let result = await skate_tricks.find({}).lean();
res.send(result);
} catch (err) {
res.send(err);
}
});
You result object is an array of object.
[
{
"trick_type": [],
"_id": "5f34a5782e0d2fe1c2847633",
"tricks": [
{
"trick_id": 0,
"trick_name": "ollie",
"trick_type": [
"flat"
],
"trick_difficulty": "n",
"trick_description": "Fundamental trick involving jumping with the skateboard. Performed by popping the tail with the back foot and sliding the front foot up towards the nose of the board. The sliding action levels the board while you are airborn."
}
]
}
]
So you have to access it by using res.send(result[0].tricks); or change your API response to return it like
I am trying to create a shard collection from node function. And I am using mongoose to do CRUD operations with mongo DB.
Below is the function which deletes the existing names collection and is creating a new collection. But not with shard key.
names.collection.drop()
.then(res => {
context.log("Item collection dropped");
names.create({store_id: "9718", item_id: "123"})
.then(res => {
context.log("res", res);
})
})
Here is the mongoose schema for that collection.
const itemsSchema = mongoose.Schema({
"store_id": {
type: String,
required: true
},
"item_id": {
type: String,
required: false
},
"ext_description": {
type: String,
required: false
}
}, { shardKey: { store_id: 1 } });
const Item = mongoose.model("names", itemsSchema, 'names');
Appreciate your time.
I'm creating an Android App (A baseball app) where I'm using MongoDB to store my data. the way I want my JSON data to be stored into the database is like this.
{"email#domain.com":{
"coachName": "Smith"
players:[
player1:{
"throws_":"n\/a",
"position":"position not set",
"number":"1",
"playerNum":"H8E83NxRo6",
"bats":"n\/a",
"team_name":"Team",
"name":"Name"}
player2:{
"throws_":"n\/a",
"position":"position not set",
"number":"1",
"playerNum":"H8E83NxRo6",
"bats":"n\/a",
"team_name":"Team",
"name":"Name"}
]
}
sorry if there is any syntax error, but essentially that is the layout i want for the JSON. Where the mongo page "id" is the persons email. and where "players" is an array of the list of players the coach has.
My question is, how can I
properly setup the Mongoose schema to look like this?
when the app sends the JSON data, how can I parse it to store the data?
and if possible (ill try and figure this part on my own if no one can) if multiple players are being added at once, how can i store them if there's already players in the array?
All of this is backend/server side, I have the android working properly, i just need help with storing it to look like this in JavaScript.
You dont want to use a dynamic variable as a field name. I'm talking about the email you have "email#domain.com". This wouldn't be good because how will you find the object. Its not common to search for object by there fields, you use the field name to describe what it is your looking for. You will need 2 models. One for player and one for coach. Coach refrences a Player in its Players array field.
If you format your JSON correctly you wont have to do any parsing, just make sure the JSON you are sending is correctly formatted.
Look at the addPlayer function.
Controller file (Answer for questions 2 and 3)
create = function(req, res) {
var coach = new Coach(req.body);
coach.user = req.user;
coach.save(function(err) {
if (err) {
return res.status(400).send({
// Put your error message here
});
} else {
res.json(coach);
}
});
};
read = function(req, res) {
res.json(req.coach);
};
addPlayer = function(req, res) {
var coach = req.coach;
console.log('updating coach', req.coach);
var player = new Player(req.newPlayer);
coach.players.push(newPlayer);
coach.save(function(err) {
if (err) {
return res.status(400).send({
// Put your error message here
});
} else {
res.json(coach);
}
});
};
Player
'use strict';
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
/**
* Player Schema
*/
var PlayerSchema = new Schema({
created: {
type: Date,
default: Date.now
},
throws: {
type: Number,
},
name: {
type: String,
default: '',
trim: true
},
position: {
type: String,
default: '',
trim: true
},
playerNum: {
type: String,
default: '',
trim: true
},
position: {
type: Number,
default: 0,
trim: true
},
teamName: {
type: String,
default: '',
trim: true
}
});
mongoose.model('Player', PlayerSchema);
Coach Schema
'use strict';
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
/**
* Coach Schema
*/
var CoachSchema = new Schema({
created: {
type: Date,
default: Date.now
},
email: {
type: String,
unique: true,
lowercase: true,
trim: true,
default: ''
},
name: {
type: String,
default: '',
trim: true
},
players: [{
type: Schema.ObjectId,
ref: 'Player'
}
});
mongoose.model('Coach', CoachSchema);
I am new to Sails.js. I am trying to fetch data from my Mongo Db database "TestDB", I have a collection name "Components", so I created a Model named Components whcih contains the attributes of my colection
Components.js
module.exports = {
attributes: {
TaskId: {
type: 'string',
required: true
},
CompName: {
type: 'string'
},
InitialAttr: {
type: 'string'
},
Value: {
type: 'string'
}
}
};
ComponentsController.js
module.exports = {
GetComponentList : function(req, res){
Components.find({ CompName: 'ImageComponent'}).exec(function(err, data) {
if (err) return next(err);
res.json(data);
});
}
};
Route:
'/comp' : {
controller: 'components',
action: 'GetComponentList'
}
The above query executes fine in MongoVUE returning the dataset, but returns
[]
in Sails.js
The Waterline ORM expects all database tables / collections to be lowercased. I'm guessing if you looked in your Mongo database you'd see there are now two collections: Components and components. If you don't care about the existing data in your db you can just delete the Components collection. Otherwise you can point your model at the existing collection using the tableName property:
module.exports = {
tableName: 'Components',
attributes: {
TaskId: {
type: 'string',
required: true
},
...etc...
}
}