MongoDB Document Validation in Meteor? - mongodb

How would one approach doing this (https://docs.mongodb.com/v3.2/core/document-validation/):
db.createCollection( "contacts",
{ validator: { $or:
[
{ phone: { $type: "string" } },
{ email: { $regex: /#mongodb\.com$/ } },
{ status: { $in: [ "Unknown", "Incomplete" ] } }
]
}
} )
In this:
// database.js
import { Mongo } from 'meteor/mongo';
export const Test = new Mongo.Collection('Test');
Thanks

you first need to define your schema in meteor.
Lists.schema = new SimpleSchema({
name: {type: String},
incompleteCount: {type: Number, defaultValue: 0},
userId: {type: String, regEx: SimpleSchema.RegEx.Id, optional: true}
});
This example defines a schema with a few simple rules:
We specify that the name field of a list is required and must be a
string.
We specify the incompleteCount is a number, which on insertion is
set to 0 if not otherwise specified.
We specify that the userId, which is optional, must be a string that
looks like the ID of a user document.
It’s pretty straightforward to validate a document with a schema. We can write:
const list = {
name: 'My list',
incompleteCount: 3
};
Lists.schema.validate(list);
In this case, as the list is valid according to the schema, the validate() line will run without problems. If however, we wrote:
const list = {
name: 'My list',
incompleteCount: 3,
madeUpField: 'this should not be here'
};
Lists.schema.validate(list);
Then the validate() call will throw a ValidationError which contains details about what is wrong with the list document.

Related

$push causing error Updating the path 'x' would create a conflict at 'x'

Given the example with Mongoose:
Schema:
const fields = {
...other fields
users: [
{ name: String, email: String, department: String, position: String, _id: false }
]
}
const Company = model('Company', fields);
Update action:
const companyId = 'company-id';
const user = { name: 'John', email: 'john#email.com' }
Company.findByIdAndUpdate(companyId, {
$push: {
users: user
}
}, { new: true })
.lean({ defaults: true })
.exec();
This causes an error:
Updating the path 'users' would create a conflict at 'users'.
I would think this would work correctly and I'm not doing anything else except pushing a new object to the array. Any help would be appreciated. Thanks!

MongoDB (mongoose): Cast to [string] failed for value

There's something wrong happens when I try to update a document in DB.
Here is Schema:
const prodSchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
description: {
type: [String]
},
})
Then I get some product from elsewhere:
const some_product = axios.get(blah blah)
And update mu document.
Note that I set up a condition for a 'description': if it has a null value, it is updated - else it remains the same:
const newProduct = {
$set: {
name: some_product.name,
description: {
$cond: {
if: {
$eq: [null, '$description']
},
then: [some_product.description],
else: '$description'
}
}
}
}
Go update (I use mongoose):
Product.updateOne({name: some_product.name}, newProduct, {some params})
And I see this:
Cast to [string] failed for value
"[{"$cond":{"if":{"$eq":[null,"$description"]},"then":["Here is some
new description of the prosuct"],"else":"$description"}}]" at path
"description"
I think the point is that the type of description in the schema is array of strings, and 'description' field in the requested 'some_product' is just a string. May be this is the issue.
But how do I solve it?
Many thanks.
var description = []
description.push(some_product.description)
const newProduct = [{
$set: {
name: some_product.name,
description: {
$cond: {
if: {
$eq: [null, '$description']
},
then: description,
else: '$description'
}
}
}
}]
put update operation in [] use update pipeline
for example
model.update({},[{$set: ...}])

GraphQL Mutation Updating Users Followers with Mongoose/MongodDB - $set is empty error

I have this mutation set up:
followUser: {
type: UserType,
args: {
_id: { type: GraphQLString },
firebaseUid: { type: GraphQLString },
following: { type: new GraphQLList(GraphQLString)},
},
resolve(parentValue, { firebaseUid, _id, following}) {
const update = {
$set: { "following": [firebaseUid] },
$push: { "following": { firebaseUid } }
}
return UserSchema.findOneAndUpdate(
{ _id },
update,
{new: true, upsert: true}
)
}
},
I'm trying to add new followers into my graphql user's collection. My user model:
const UserSchema = new Schema(
{
firebaseUid: String,
following: [{ type: Schema.Types.ObjectId, ref: 'User' }],
followers: [{ type: Schema.Types.ObjectId, ref: 'User' }],
},
{ timestamps: true }
);
module.exports = mongoose.model("User", UserSchema);
So at first, the user doesn't have any followers, so it won't have that field yet. When user adds someone to their friends list, thats when the field will appear in mongodb. Right now I'm getting this error:
"message": "'$set' is empty. You must specify a field like so: {$set: {<field>: ...}}",
I'm not sure if I'm doing the $set correctly.
The UserType
const UserType = new GraphQLObjectType({
name: "User",
fields: () => ({
_id: { type: GraphQLString },
firebaseUid: { type: GraphQLString },
following: { type: new GraphQLList(GraphQLString) },
followers: { type: new GraphQLList(GraphQLString) },
...
})
});
edit:
current mongodb data collection:
_id: ObjectId("5e5c24111c9d4400006d0001")
name: "Mr. Smith"
username: "mrsmith"
after running the update
_id: ObjectId("5e5c24111c9d4400006d0001")
name: "Mr. Smith"
username: "mrsmith"
following: ["fdsaduybfeaf323dfa"] // <-- this gets added
Currently mongooses validator is rejecting the update. To fix this you need the following:
You only need to $push since it will automatically create an array if the property does not exist
You should remove the extra { } around the firebaseUid in the $push because otherwise the following array will contain objects with a firebaseUid property instead of directly containing the Uid (or would if the schema validator allowed it)
Mongo ObjectIds can only be converted from strings when they are 12-byte hexadecimal, and firebaseUid is not, so the schema should be typed to String instead of ObjectId as the validator will reject the field for update otherwise.

Push item to array, only first property is included. Mongoose

Schema:
let projectSchema = new Schema({
filters: [
{
name: { type: String, required: true},
items: {
q: { type: Number, required: true}
}
}
],
});
Update function:
const project = await mongoose.model('project').findById(id).exec();
console.log(filter); // { name: 'abc', items: [ { q: 3}]
project.filters.push(filter);
console.log(project.filters); // { _id: "123", name: 'abc' } // items array is missing
await project.save();
When I fetch a document via mongoose, then add an item to an array of that doc, only the first property is included.
Why is that?
I prefer not to use $push since the benefits of mongoose (validation etc) is not respected when $push is used.
The items field is an object instead of an array. Change your schema:
let projectSchema = new Schema({
filters: [
{
name: { type: String, required: true},
items: [ // square brackets here
q: { type: Number, required: true}
]
}
],
})

Avoid insertion in mongoDB Without Data

How can i avoid the insertion in mongoDB if there is no data. Because every time i use insert command it is creating _id without data.
Example : db.collection_name.insert({})
is creating _id in document. How to avoid it.
You can use mongoose ORM and can define validators like:
var UserSchema = new Schema({
name: { type: String, required: true }
});
Which will generate an error message that looks like:
name:
{ message: 'Validator "required" failed for path name',
name: 'ValidatorError',
path: 'name',
type: 'required' } }
MongoDB 3.2 has schema validation integrated.
So you can just check if "name" property exists, if not then the validation fail and then the Document will be not inserted at all.
https://docs.mongodb.com/v3.2/core/document-validation/
db.createCollection( "contacts",
{ validator: { $or:
[
{ phone: { $type: "string" } },
{ email: { $regex: /#mongodb\.com$/ } },
{ status: { $in: [ "Unknown", "Incomplete" ] } }
]
}
} )