mongoDB schema changes results in error for old users? - node.js

I have a schema in my server like this:
deliveryAddress : {
city: String,
state: String,
country: String,
zipcode: String
}
but because of future enhancement we were required to add phone number to this deliveryAddress collection object. but the user who are already registered will face the problem how do i solve this.
The schema should look like this in future:
deliveryAddress : {
city: String,
state: String,
country: String,
zipcode: String,
phoneNumber:String
}

Related

How to share fragments between multiple types in Graphql schema

I'm using node.js as backend and want to define theses two types that share many fields in a graphql file:
type Customer {
_id: ObjectID,
first_name: String
last_name: String,
mobile: String,
national_code: NonNegativeInt,
# plus some different fields
}
type CustomerInformation{
_id: ObjectID,
first_name: String
last_name: String,
mobile: String,
national_code: NonNegativeInt,
# plus some different fields
}
So, we can define a fragment:
fragment CoreCustomerFragment on Customer {
_id: ObjectID,
first_name: String
last_name: String,
mobile: String,
national_code: NonNegativeInt,
}
So what is the correct way of reusing the defined fragment in both Customer and CustomerInformation types? I tried the below code:
type Customer {
...CoreCustomerFragment,
field1: String
}
type CustomerInformation{
...CoreCustomerFragment,
field2: String
}
and I got errors like Customer must define one or more fields

How to delete the data across the collections

Let's say, I have collections like
let employee = mongoose.Schema({
name: String,
email: String,
department: String,
doj: Date,
address: String
});
let student= mongoose.Schema({
name: String,
email: String,
department: String,
doj: Date,
address: String
});
let manager= mongoose.Schema({
name: String,
email: String,
department: String,
doj: Date,
address: String
});
in my database. I need to delete every data which has department "Computer Science" in each collection(employee, student, manager). I don't know how to do it. I tried deleting data by getting collection names from my database first then querying to remove each data as I said, but it doesn't work as I expected, always return error"db.getCollectionName is not a function". Any idea how to remove data across the multiple collections at the same time?. I am using node js,express and MongoDB.
To delete matching records for all collections, you can loop through all the models you have registered with Mongoose.
Object.keys(connection.models).forEach(async(collection) => {
const usersss = mongoose.model(collection)
await usersss.deleteMany({ defaultAccountId: userParam.defaultAccountId, grnNo: userParam.grnNo })
})

Creating different types of users in mongodb

I want to create an API to register, login and other things. two types of users
A teacher and a student , I'm using MongoDb and defining the schema.
const UserSchema = new Schema({
studentInfo : {
name: String,
email: String,
password: String,
birthday: Date,
state: String,
zip_code: String,
address: String,
phone_number: String,
},
teacherInfo : {
name: String,
email: String,
password: String,
birthday: Date,
state: String,
zip_code: String,
address: String,
phone_number: String,
course: {
title: String,
price: Number,
description: String
}
},
role: String
});
is this a good approach? or there is a better way?
I added the role field to perform route guarding on the front end.
I'm using Nodejs and Express.
any help will be much appreciated, thank you.
This is one way of embedding both student and teacher object in the same document and you can simply get data with single query. Although you don't need to separately embed the common fields in object like name, email, password, phone_number etc. teacherInfo would be like this
teacherInfo : {
course: {
title: String,
price: Number,
description: String
}
}
You can create different schemas for student and teacher (as they are unique and you might need them independent sometimes), and make User as the base model.
var User= new Schema({
name: String,
email: String,
password:String,
birthday: Date,
state: String,
zip_code: String,
address: String,
phone_number: String,
_teacher:{type:Schema.Types.ObjectId, ref:'Teacher'},
_student: {type:Schema.Types.ObjectId, ref:'Student'}
});
If _teacher has a value then the user can be considered as a teacher.
If _student has a value then the user can be considered as a student.
//Teacher Model
var Teacher = new Schema({
course: {
title: String,
price: Number,
description: String
},
//other teacher's fields
})
//Student Schema
var Student= new Schema({
//student's fields if you need in future
})

Node.js Mongodb graphql

I have started a project that in using node.js and express and it's connected to a mongodb, this database has three collections (Participants, Houses, and activities), one participant can have one house and any activities! I have already done the query in graphql for each one, but I don't know how I can do the query and retrieve the relations between them. For example how I can know with participants are on a determined house...
Please go through the GraphQL documentation
GraphQL documentation out there tends to focus on queries, less on mutations, less on defining a schema, even less on setting up a server, and even less less on binding the server to an actual database.
type participant{
_id: String
title: String
participantId:String
........
house : house
}
type house{
_id: String
title: String
houseId:String
........
activities : [activity]
}
type activity{
_id: String
name: String
content: String
post: Post
}
This is sample model, you can design schema as per your requirement
Now you can try query like this
query {
participants{
_id
title
}
house {
_id
houseId
comments {
_id
postId
content
}
}
}
This is sample query format
My schema is:
type Participant {
_id: ID!,
CodP: String!,
User: String!,
Birth: Date,
Country: String,
Email: String,
ApplyDate: Date,
LUG: String,
Status: String,
Control: String,
CodH: House,
CodA: [Activitie],
createAt: Date,
updateAt: Date,
}
type Activitie {
_id: ID!,
CodA: String,
Day: String,
StartTime: Date,
EndTime: Date,
Where: String,
Name: String,
Description: String,
}
type House {
_id: ID!,
CodH: String,
Name: String,
Onwer: String,
Address: String,
Local: String,
Contact1: String,
Contact2: String,
Contact3: String,
Email: String,
URL: URL,
CoordDD: String,
CoordDMS: String,
URLGoogleMaps: URL,
IMG: String,
Group: String,
ImgGoogleMaps: String,
I1: String,
Info: String,
I2: String,
N1: String,
I3: String,
N2: String,
I4: String,
N3: String,
I5: String,
N4: String,
I6: String,
N5: String,
I7: String,
N6: String,
I8: String,
N7: String,
I9: String,
N8: String,
I10: String,
N9: String,
I11: String,
Final: String
}
type Query {
getParticipant(_id: ID): Participant
getParticipantAll: [Participant]
getActivitie(_id: ID): Activitie
getActivitieAll: [Activitie]
getHouse(_id: ID): House
getHouseAll: [House]
getHouseCod(CodH: String): [House]
}
But my problem in the Resolver, simples one i can do it, for example:
import House from '../../models/House';
export default {
getHouse: (_, { _id }) => House.findById(_id),
getHouseCod: (_, { CodH }) => House.find({CodH}),
// createdAt vai permitir ordenar pela data de criação //
getHouseAll: () => House.find({}).sort({ createdAt: -1 }),
};

mongoose geojson in schema, "Can't extract geo keys" error

I have a mongodb collection with a defined schema, and I updated this schema to include lat/lon coordinates.
old version:
var schema = mongoose.Schema({
id: String,
name: String,
address: String,
city: String,
zip: String,
country: String,
phoneNumber: String,
mobile: String,
website: String,
email: String,
});
new version
var schema = mongoose.Schema({
id: String,
name: String,
address: String,
city: String,
zip: String,
country: String,
phoneNumber: String,
mobile: String,
website: String,
email: String,
location: GeoJSON.Point
});
schema.index({ location: '2dsphere' });
GEOJSON.Point comes from mongoose-geojson-schema and looks like this:
GeoJSON.Point = {
'type' : { type: String, default: "Point" },
coordinates: [
{type: "Number"}
]
}
The collection already contained data before I added the location property.
Apparently what happens now is that for some reason mongodb uses { coordinates: [], type: "Point" } as default value for the existing documents, and I get errors like these:
MongoError: Can't extract geo keys: { _id: ObjectId('5637ea3ca5b2613f37d826f6'), ...
Point must only contain numeric elements
I have looked at how to specify a default value in a schema, but I see no way of setting the value to null in case of a GeoJSON.Point data type.
I also tried
db.collection.update({},{$set:{location:null},{multi:true})
but that didn't seem to help either.
Is it because of the index on the location?
I think you need to upgrade GeoJSON.Point to a sub document with a proper schema:
GeoJSON.Point = new mongoose.Schema({
'type' : { type: String, default: "Point" },
coordinates: [ { type: "Number" } ]
});
Combined with the minimize option, which it enabled by default, this will make Mongoose only save the location property if it is actually set.
I would suggest you to not use GeoJSON.Point as a schema type. Just use mixed object type and everything will work properly.
location: Schema.Types.Mixed

Resources