How to find a particular sub-document in MongoDB? - database

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.

Related

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

MongoDB query to find an ID of a referenced model

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

Mongoose enum Validation on String Arrays?

Is it possible to use enum validation on type: [String]?
Example:
var permitted = ['1','2','3'];
var exampleSchema = new Schema({
factors: {
type: [String],
enum: permitted,
required: "Please specify at least one factor."
}
});
I would have expected that factors would only be able to contain the values in permitted.
This is working fine for me (mongoose#4.1.8)
var schema = new mongoose.Schema({
factors: [{type: String, enum: ['1', '2', '3'], required: ...}]
...
})
Note I'm using an Array of Objects
As of mongoose version 5.0.6 and higher, the OP issue now works!
factors: {
type: [String],
enum: permitted,
required: "Please specify at least one factor."
}
Reference
https://github.com/Automattic/mongoose/issues/6204#issuecomment-374690551
TRY THIS
let inventory_type_enum = ["goods", "services"];
inventory_type: {
type: String,
enum: inventory_type_enum,
validate: {
// validator: (inventory_type) => !inventory_type.enum.includes(inventory_type),
validator: (inventory_type) => inventory_type_enum.includes(inventory_type),
message: languages('general_merchandise_model','inventory_type')
},
required : [true, languages('general_merchandise_model','inventory_type_required')],
},
Mongoose before version 4.0 didn't support validation on Schema static methods like .update, .findByIdAndUpdate, .findOneAndUpdate.
But it supports on instance method document.save().
So, either use document.save() for inbuilt initiating validation
or this { runValidators: true } with methods like .update, .findByIdAndUpdate, .findOneAndUpdate.
reference:
Mongoose .update() does not trigger validation checking
if you have enuns or you have object enuns
brand: {
type: String,
required: true,
enum: Object.values(TypeBrandEnum)
},
you can use something like this
{
factors: [
{
type: [String],
enum: ['1', '2', '3'],
},
],
}

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)

Fail to PUT second data in mongodb via Angularjs

I am using Angularjs to update the following expressjs Team model, but one weird thing is that when I PUT the first one to the database, it works.
var TeamSchema = new Schema({
title: {
type: String,
unique: true
},
image: String,
homeColor: String,
guestColor: String,
thirdColor: String,
created: {
type: Date,
default: Date.now
},
});
If the database consists of exactly one data, it will have the following errors:
{ [MongoError: E11000 duplicate key error index: acleague.teams.$prefix_1 dup key: { : null }]
name: 'MongoError',
err: 'E11000 duplicate key error index: acleague.teams.$prefix_1 dup key: { : null }',
code: 11000,
n: 0,
lastOp: { _bsontype: 'Timestamp', low_: 1, high_: 1399820159 },
connectionId: 69575,
ok: 1 }
I can sure that I don't have an $prefix_1 attr for team model.
Anyone can help me solve this problem? It already spends me lots of time of it.

Resources