Node.js Mongodb graphql - node.js

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 }),
};

Related

MongoDB/Mongoose: Sorting within a populated field

I am pretty new to MongoDB and i am unable to find a solution to the following:
I am trying to sort personnel after their ranks.
CollectionPerson: _id, name, {rank_id}
CollectionRank: _id, RankName, level
What I am trying to accomplish ist to get a list in order of the rank level.
Any solution or direction pointing would be nice.
/edit:
MyModels:
const RankSchema = new Schema({
level: Number,
dgGrp: Number,
dgSold: String,
dgNATO: String,
hut: {
bezX: String,
bezM: String,
bezS: String,
img: String
},
lut: {
bezX: String,
bezM: String,
bezS: String,
img: String
},
mut: {
bezX: String,
bezM: String,
bezS: String,
img: String
}
});
const PersonalSchema = new Schema({
name: {
type: String,
required: true,
},
vname: String,
pNum: {
type: String,
default: '01010101',
},
pKenn: {
type: String,
default: '010101-A-01010',
},
dg: {
type: Schema.Types.ObjectId,
required: true,
ref: 'Rank'
},
uni: String,
sex: String,
konf: String,
adresse: {
str: String,
plz: Number,
ort: String,
land: String,
staat: String
}
});
My Query:
const personal = await Personal.find({}).populate({ path: 'dg', options: { sort: { level: 1 } } });
Population is done on client side by Mongoose after the query fetching the base documents has already executed. As such, sorting the base documents has already been done (if requested).
You can:
Construct an aggregation pipeline, $lookup and $sort yourself.
Let Mongoose populate your documents then reorder them as you wish in your application.

How to find documents in mongoose by populate field?

I have an issue with mongoose. When I make some field referenced to other collection, I lose ability to search by this field. I don't know how to describe my problem correctly, so look at the examples please.
Schema:
var PostSchema = new Schema({
title: String,
content: String,
url: String,
author: { type: Schema.ObjectId, ref: 'User'},
mainImage: String,
type: String
});
Query:
Post.find({author: user._id})
.then(posts => res.send(posts))
.catch(err => res.status(500).send(err))
Returns nothing. But if I change "author" field to String, it will works, but without populate. :(
Upd:
I can't believe. I made this:
var PostSchema = new Schema({
title: String,
content: String,
url: String,
author: {type: String, ref: 'User'},
mainImage: String,
type: String
});
Just change type to string. Omg I can't figure out how it working. How mongoose knows which field I need to compare in ref collection? I mean there is no direct link to "_id" field (see query). Can someone explain?
Upd2:
Auhtor schema:
var UserSchema = new Schema({
id: String,
about: String,
firstname: String,
lastname: String,
email: String,
avatar: String,
city: String,
country: String,
dateOfBirth: String,
password: String,
},
{
timestamps: true
})
As you can see, I using additional "id" field just in purpose to give users simple numeric id for url (/id1 etc). But I am sure this isn't the source of the problem :)
Try change the type: Schema.ObjectId to type: mongoose.Schema.Types.ObjectId

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
})

Swap an object in a Mongoose array with another object in the array of another document

Consider this schema:
let userSchema = new Schema({
email: { type: String, required: true },
password: { type: String, required: true },
books: [{
owner: String,
cover: String,
title: String,
link: String,
requestsReceived: { requestingUser: String, bookOffered: String },
requestsSent: { toUser: String, bookWanted: String },
beingRequested: { type: Boolean, default: false },
beingSent: { type: Boolean, default: false }
}],
ip: String
});
the books array contains objects which hold a variety of information. How can I take a certain book object from array of document 1 and swap it with array of document 2 preferably with the least amount of queries to the DB. (i.e. between two different user documents)
I know this is a bit difficult. Much appreciated.

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