MongoDB query to find an ID of a referenced model - database

I am trying to find an ID of a model which is referenced to another model.
I have a User model which consist of an array of challenges, I have to find an ID of a challenge which exist for a particular user
My user model:
var UserSchema = new mongoose.Schema({
image: String,
displayName: String,
firstName: String,
lastName: String,
password: String,
email: String,
createdAt: Date,
accessToken: String,
isLoggedIn: Boolean,
challenges:[
{
type: mongoose.Schema.Types.ObjectId,
ref:"Challenge"
}
]
});
My challenges model:
var ChallengeSchema = new mongoose.Schema({
winner: Boolean,
score: String
});
For eg:
If my user id is 1 and challenge id is 89, I have to check if the challenge id is present for that particular user whose id is 1.

MongoDB is document-oriented and don't have joins. In theory all data about one object is stored in one document in such dbs.
So in your case we have users with array of challenges inside.

Here is the query to check if the challenge id (89) is present for that particular user whose id is 1.
User.count({
_id: 1, // User ID
challenges: {
"$in": [89] // Challenge Id
}
}).exec(function(err, count){
if(err){
// Handle error
} else {
if(count > 0){
// If count greater than 0 than user(ID-1) contains challenge(ID-89)
}
}
});

Related

How to find a particular sub-document in MongoDB?

This thread states that it is not a very good idea to create _id in a sub-document of MongoDB.
Mongo _id for subdocument array
I have locations and their reviews in a collection:
So, what would be the way to find a unique sub-document?
What can be set as a primary key for review sub-document?
var mongoose = require('mongoose')
var openingClosingTimeSchema = new mongoose.Schema(
{
days: {type: String, required: true},
opening: String,
closing: String,
closed: {type: String, required: true}
}
)
var reviewSchema = new mongoose.Schema(
{
author: String,
rating: {type: Number, required: true, min: 0, max: 5},
reviewText: String,
createdOn: {type: Date, default: Date.now}
}
)
var locationSchema = new mongoose.Schema(
{
// 'required' keyword is for validation.
name: {type: String, required: true},
address: String,
// 'default' keyword can be with or without quotes.
// When defining multiple properties for a field, {} are required.
rating: {type: Number, default: 0, min: 0, max: 5},
facilities: [String],
// Nest 'openingClosingTimeSchema' under 'locationSchema'.
openingTimes: [openingClosingTimeSchema],
// Nest 'reviewSchema' under 'locationSchema'.
reviews: [reviewSchema]
}
)
it is not a very good idea to create _id in a sub-document of MongoDB
This is not a universally applicable guideline.
If you need to identify subdocuments in an array, an _id field would be helpful (or any other field that would serve the same function).
If you don't need to identify subdocuments, you don't need an identification field.
Since you are in the first category it's perfectly ok to have an _id field in your use case.

How to add value to array element withing collection using mongoose?

I have written the following mongoose function to create new document in mongodb
createdata: (body) => {
let sEntry = new SData(Object.assign({}, {
dataId: body.DataId
//,
//notes.message: body.message
}));
return sEntry.save();
}
Here sData schema includes notes array schema within it.
I am not able to add value to message within notes [] using notes.message: body.message
My schema definition is as follows:
var nSchema = new Schema({
_id: {type:ObjectId, auto: true },
message: String
});
var sSchema = new Schema({
_id: {type:ObjectId, auto: true },
dataId: { type:String, unique: true },
notes: [nSchema]
}
I also want to mention that for every dataId there can be multiple notes [] entries. However, SData can have only unique row entry for every dataId.
I want notes to be an array within SData collection. How it can be achieved without creating separate notes collection? How should i modify createdata to accommodate all the given requirements.
Use references for other collection mapping and use populate when fetching
Schema Design
var sSchema = new Schema({
_id: {type:ObjectId, auto: true },
dataId: { type:String, unique: true },
notes: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'nSchema',
}]
}
Adding Data
createdata: (body) => {
let sEntry = new SData({
dataId: body.DataId,
notes: [nSchemaIds]
});
return sEntry.save();
}

How to save an empty array as property of a nested object in mongoose?

I have the following code:
var lesson = new Lesson({
classroomId: req.params.classroomId,
name: req.body.name,
startDate: startDate1,
endDate: endDate1,
teacher: {
_id: classroom.teacher._id,
attendance: [],
},
students: [],
});
lesson.save();
When I check in the backend, the teacher key just has the _id property and the attendance property wasnt saved. I suspect this is because it is an empty array. How can I save an empty array like this?
It may be because Lesson Schema is not defined properly. Did you try setting...
mongoose.Schema({
.....
teacher: {
...
attendance: { type: Array, default: [] }
}
...
});

location object expected, location array not in correct format

I have spent doing such a straight forward thing. I just want to do a CRUD operation on a user model using nodejs, mongoose, restify stack. My mongo instance is on mongolab.
The user should contain a "loc" field . User schema is as follows :
var mongoose = require('mongoose')
var Schema = mongoose.Schema;
var userSchema = new Schema( {
email_id : { type: String, unique: true },
password: { type: String},
first_name: String,
last_name: String,
age: String,
phone_number: String,
profile_picture: String,
loc: {
type: {},
coordinates: [Number]
}
});
userSchema.index({loc:'2d'});
var User = mongoose.model('user', userSchema);
module.exports = User;
the rest api used to post is as follows :
create_user : function (req, res, next) {
var coords = [];
coords[0] = req.query.longitude;
coords[1] = req.query.latitude;
var user = new User(
{
email_id : req.params.email_id,
password: req.params.password,
first_name: req.params.first_name,
last_name: req.params.last_name,
age: req.params.age,
phone_number: req.params.phone_number,
profile_picture: req.params.profile_picture,
loc: {
type:"Point",
coordinates: [1.0,2.0] // hardcoded just for demo
}
}
);
user.save(function(err){
if (err) {
res.send({'error' : err});
}
res.send(user);
});
return next();
},
Now when i do a POST call on curl -X POST http://localhost:3000/user --data "email_id=sdass#dfAadsfds&last_name=dass&age=28&phone_number=123456789&profile_picture=www.jakljf.com&longitude=1.0&latitude=2.0"
I get the following error
{
error: {
code: 16804
index: 0
errmsg: "insertDocument :: caused by :: 16804 location object expected, location array not in correct format"
op: {
email_id: "sdass#dfAadsfdsadkjhfasvadsS.com"
password: "sdass123DadakjhdfsfadfSF45"
first_name: "shaun"
last_name: "dass"
age: "28"
phone_number: "123456789"
profile_picture: "www.jakljf.com"
loc: {
coordinates: [2]
0: 1
1: 2
-
type: "Point"
}-
_id: "55efc95e0e4556191cd36e5e"
__v: 0
}-
}-
}
The location field is giving problems as the POST call works just fine if i remove the loc field from model
Below are the hits/trials I did :
1) Change userSchema.index({loc:'2d'}); to userSchema.index({loc:'2dsphere'});
2) Changing loc schema to everything given in Stackoverflow. I would like to know the right way to define this though.
3) Passing the hardcode 2d array but still it says Location object expected, location array not in correct format" what format is required for this ?
Any help in this regard is greatly appreciated. Thanks.
MongoDB 2d index requires the legacy coordinates pairs format, which is just an array of coordinates like [1, 2].
If you need GeoJSON support, please use the 2dsphere index.
userSchema.index({loc:'2dsphere'});
If you are using Spring Boot make sure you set the index type to 2DSphere:
#GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE) GeoJsonPoint location;

how to merge field from mongodb collection

that's my model
var schema = new mongoose.Schema({
title: String,
link: String,
gid: Number,
posts: [],
date: { type: Date, default: Date.now },
}, { collection: 'Group' });
var Group = mongoose.model('Group', schema);
I need to get all posts objects from collection by one query.
Using mongoose it should work with the following statement using a projection to return only the posts field (and the _id field)
Group.find({},{"posts":1} ).exec(callback)
To only get all posts you have to use an aggregation.
Group.aggregate([{$unwind : "$posts"}, {$project: {"post":"$posts", _id:0}}]).exec(callback)

Resources