Here is what I'm trying to do:
SimpleSchema.FaqSchema = new SimpleSchema
order:
type: Number
autoValue: ->
# somehow increment this by 1
updatedAt:
type: Date
autoValue: ->
new Date
updatedBy:
type: String
autoValue: ->
Meteor.userId()
question: type: String
answer: type: String
Unfortunately, there is nothing in Meteor documentation or simpleschema docs for this matter which explains how to do it. There is mongo docs here : http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/
However, this doesn't really help.
Any help is appreciated. The schema is in coffeescript but can be converted using http://js2.coffee/
Create a Meteor method on the server side that increments the order field by 1 during inserts. This method uses the meteor-mongo-counter package which implements the "Counters Collection" technique described in the MongoDB documentation Create an Auto-Incrementing Sequence Field:
Server
Meteor.methods
"insertDocument": (doc) ->
doc.order = incrementCounter "order"
MyCollection.insert doc
doc.order
Client
doc =
question: "Question 1"
answer: "Answer 1"
# Instead of inserting with Collection.insert doc, use Meteor.call instead
Meteor.call "insertDocument", doc, (err, result) ->
if result console.log "Inserted order number #{result}"
Related
I am using loopback4 with MongoDB.
I have a counter property in my model, and would like to do atomic operation to increment/decrement that counter.
My implementation now is using ExtendedOperators $inc to add or sub calculations.
But I found that despite of my jsonSchema set to minimum:0, the counter will be negative value when $inc:{counter:-1} at counter value 0.
I think I can use Mongo Document Validation to set value range constraint, But I cant find the right way in repository code to do this.
Should I set it manually through Mongo Shell?
But how can I do error handling?
model
#property({
type: 'number',
jsonSchema:{
minimum:0,
}
})
count: number;
controller
async incrementCountById(
#param.path.string('id') id: string
): Promise<void> {
await this.userRepository.updateById(id, {$inc: {count: -1} });
}
repository
const config = {
allowExtendedOperators: true,
};
Any advice would be appreciated:)
I am using mongoose and MongoDB. Is there any way to update the entire schedule array in the schema? or do I have to use a for loop and insert one by one?
My req.body is an array to replace the entire schedules array object.
[{"_id":"1","description":"hi","time":"Jul 29, 2020 8:55 PM","url":"aaa.com"},{"_id":"2","description":"hi","time":"Jul 29, 2020 8:58 PM","url":"bbb.com"},{"_id":"3","description":"hi"}]
here is my schema.
const schedule = new mongoose.Schema({
user_id: Number,
schedules: [{
description: String,
time: String,
url: String
}]
});
Thank you.
If you're using mongoose, we can avoid using $set. #jitendra's answer is a pure mongodb query which you could run in the mongo shell.
You can refer to this link https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate .
As the link says,
var query = { name: 'borne' };
Model.findOneAndUpdate(query, { name: 'jason bourne' }, options, callback)
// is sent as
Model.findOneAndUpdate(query, { $set: { name: 'jason bourne' }}, options, callback)
This helps prevent accidentally overwriting your document with { name: 'jason bourne' }.
So in your case we just need to write :
Schedule.findOneAndUpdate({_id: "id_of_object"}, {schedules: req.body});
That should do it for you. But internally, as the doc says, it is being sent as:
Schedule.findOneAndUpdate({_id: "id_of_object"}, {$set: {schedules: req.body}})
Ofcourse this assumes that your req.body consists of the array of schedules only. Most likely you're sending it as an object from the front end so maybe it's req.body.object_name . Up to you.
You can update the entire schedule array by using $set , try as follow:
db.collection.update({query},{ $set: { schedules: req.body } },{option});
Here your req.body should be the array with same keys as per defined in your schema.
I couldn't understand that for what purpose mongoose schemaType is used for. If someone could explain it will be helpful.
I'm have to reference another schema from a schema i want to know if we can get the details of all schema together when we do a findOne() on mongoose.
mixed schema means whatever you want the type to be. if you input a String, Number, Date, mongoose will let you do that. However according to documentation, mongoose ref does not work with mixed.
Note: ObjectId, Number, String, and Buffer are valid for use as refs.
if you use mixed, and ref it, you won't be able to query it back.
If you start all over(delete the database and reinsert again), use ObjectId instead of Mixed.
var storySchema = Schema({
author : { type: ObjectId, ref: 'Person' },
});
If you wish to retain old database, the best way is to change mixed to string
var storySchema = Schema({
author : { type: String, ref: 'Person' },
});
How to create a date field with default value,the default value should be current timestamps whenever the insertion happened in the collection.
Thats pretty simple!
When you're using Mongoose for example, you can pass functions as a default value.
Mongoose then calls the function for every insertion.
So in your Schema you would do something like:
{
timestamp: { type: Date, default: Date.now},
...
}
Remember to only pass the function object itself Date.now and not the value of the function call Date.now()as this will only set the Date once to the value of when your Schema got created.
This solution applies to Mongoose & Node.Js and I hope that is your usecase because you did not specify that more precisely.
Use _id to get the timestamp.
For this particular purpose you don't really need to create an explicit field for saving timestamps. The object id i.e. "_id", that mongo creates by default can be used to serve the purpose thus, saving you an additional redundant space. I'm assuming that you are using node.js so you can do something like the following to get the time of particular document creation:
let ObjectId = require('mongodb').ObjectID
let docObjID = new ObjectId(<Your document _id>)
console.log(docObjID.getTimestamp())
And, if you are using something like mongoose, do it like this:
let mongoose = require('mongoose')
let docObjID = mongoose.Types.ObjectId(<Your document _id>)
console.log(docObjID.getTimestamp())
Read more about "_id" here.
When Creating Document, timestamps is one of few configurable options which can be passed to the constructor or set directly.
const exampleSchema = new Schema({...}, { timestamps: true });
After that, mongoose assigns createdAt and updatedAt fields to your schema, the type assigned is Date.
You would simply do this while inserting... for current timestamp.
collection.insert({ "date": datetime.now() }
Let's consider the user schema in which we are using created date, we can use the mongoose schema and pass the default value as Date.now
var UserSchema = new Schema({
name: {type: String, trim: true},
created: {type: Date, default: Date.now}
});
If we want to save timetamp instead of number then use Number isntead of number like that
var UserSchema = new Schema({
name: {type: String, trim: true},
created: {type: Number, default: Date.now}
});
Note:- When we use Date.now() in the default parameter then this will
only set the Date once to the value of when your Schema got created,
so you'll find the dates same as the that in the other document. It's better to use Date.now instead of Date.now().
Here's a command that doesn't set a default, but it inserts an object with the current timestamp:
db.foo.insert({date: new ISODate()});
These have the same effect:
db.foo.insert({date: ISODate()});
db.foo.insert({date: new Date()});
Be aware that Date() without new would be different - it doesn't return an ISODate object, but a string.
Also, these use the client's time, not the server's time, which may be different (since the time setting is never 100% precise).
I just wish to point out that in case you want the timestamp to be stored in the form of an integer instead of a date format, you can do this:
{
timestamp: { type: Number, default: Date.now},
...
}
Thanks friends ..
I found another way to get timestamp from _id field. objectid.gettimestamp() from this we can get it time stamp.
This is a little old, however I fount when using the Date.now() method, it doesn't get the current date and time, it gets stuck on the time that you started your node process running. Therefore all timestamps will be defaulted to the Date.now() of when you started your server.
One way I worked around this was to do the following:
ExampleSchema.pre('save', function (next) {
const instanceOfSchema = this;
if(!instanceOfSchema.created_at){
instanceOfSchema.created_at = Date.now();
}
instanceOfSchema.updated_at = Date.now();
next();
})
createdAt: {type: Date, default:Date.now},
MongoDb returns ids of the form _id. I would like to make sure that the frontend (ember.js app) always receives id instead. I could write a serializer on the client, but I think there's probably a much easier solution that could either be implemented at the Database level or within the express server app.
I tried using virtual attributes, but this did'nt seem to work.
ActionSchema = mongoose.Schema(
title: type: mongoose.Schema.Types.Mixed
reduction: type: Number
description: type: mongoose.Schema.Types.Mixed
category: type: String
)
ActionSchema.virtual('id').get(->
#_id
)
I solved this using custom toJSON method. In model after schema declaration:
schema.options.toJSON =
transform: (doc, ret, options) ->
ret.id = ret._id
delete ret._id
delete ret.__v
ret
Then in my controller I've used item.toJSON() when I wanted to return correctly formatted JSON response.
I found my answer using this blog post:
http://ryanchristiani.com/working-with-ember-data-node-express-and-mongodb/
The simple way is to write a rest serializer in Ember like so:
export default DS.RESTSerializer.extend({
primaryKey: '_id',
serializeId: function(id) {
return id.toString();
}
});