Add automatic createdAt and updatedAt timestamps in migration - javascript

I'm doing a Sequelize migration which adds a new table.
In this table I want to add the timestamps createdAt and updatedAt that are automatically updated and my migrations works using literals like this:
createdAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
},
updatedAt: {
type: Sequelize.DATE,
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
},
I've to only add timestamps: true in the options but the timestamps are not automatically updated.
Can I do this without using literals?

I had a similar problem in setting the defaultValue for the timestamp fields.
I came across this issue: https://github.com/sequelize/sequelize/issues/645 which suggests calling Sequelize.fn('NOW') to automatically update the timestamps.
Seemed to work in my case.

Related

mongodb not detecting unique value in my node js project

I'm working on mongodb with node js and I realized that even though I used the unique true property on unique fields in my project, I realized that it doesn't work, what is the reason?
my code is like this
const CourseSchema = new Schema({
name: {
type: String,
required : true,
unique:true
},
description: {
type: String,
required: true,
trim: true,
},
createdAt: {
type: Date,
default: Date.now,
},
});
i want to prevent this code from saving duplicate usernames.
Such a check if not directly possible with the mongoDB library. However it is supported out of the box if you use mongoosejs
It may be possible that you already have duplicate values in your document before defining this property Delete the messed data from the MongoDB collections,
or make sure that mongodb auto indexing is true
mongoose.connect('url', {
useNewUrlParser: true,
useCreateIndex: true,
autoIndex: true,
})
I tried many ways, but I realized that this problem is version-related.
I found the solution by updating the version, thank you for your solution support.

How to control sort direction in a list query in AWS-Amplify with GraphQL

I've seen several useful posts on how to create schemas in AWS-Amplify's GrahphQL API package that will return a sorted response. In brief, if you have the following in your schema.graphql file
type Record #model
#key(name: "byDateCreated", fields: ["status", "createdAt"], queryField: "RecordsByDateCreated") {
id: ID!
status: RecordStatus!
description: String!
createdAt: String
}
It will create a custom query called recordsByDateCreated. Using it as follows (js here, folks):
await API.graphql(graphqlOperation(recordsByDateCreated, { status: 'unused', limit: 10 }));
will return the first 10 records in the table sorted by their createdAt values. By default, this data will be returned in ascending order, which means that you'll get the oldest records first.
However, what I need is a response that has the newest records first. What do I have to add to in schema or my query so I can set the order of the sorting?
(Spoiler alert: I'm answering my own question here in case anyone else is looking for help with this.)
You would need a way to order the table's records in descending order. If you go and look at the file generated by AWS-Amplify you'll see that the new query you've created accepts a series of arguments:
export const recordsByDateCreated = /* GraphQL */ `
query RecordsByDateCreated(
$status: RecordStatus
$createdAt: ModelStringKeyConditionInput
$sortDirection: ModelSortDirection
$filter: ModelRecordFilterInput
$limit: Int
$nextToken: String
) {
RecordsByDateCreated(
status: $status
createdAt: $createdAt
sortDirection: $sortDirection
filter: $filter
limit: $limit
nextToken: $nextToken
) {
items {
id
description
status
createdAt
updatedAt
}
nextToken
}
}
`
It turns out that if you know what the possible values are for ModelSortDirection (they are are 'ASC' and 'DESC') you can pass one in as one of the variables arguments when you make that query like so:
await API.graphql(graphqlOperation(recordsByDateCreated, { status: 'unused', limit: 10, sortDirection: 'DESC' }));
(Note that the key for the variable you're passing is sortDirection and not $sortDirection, or ModelSortDirection.)
I couldn't find this in AWS-Amplify's docs and relied on other posts that I've found. If you've found any documentation relevant to this then maybe you could add a link in the comments.
(Can't comment with a reputation below 50 lol so need to make a whole other answer)
As you mentioned adding sortDirection as one of the variables arguments allows you to choose the direction, but also if you're looking to sort the items by a specific attribute other than the default one, you'll have to make that choice in the graphql schema model definition.
So for the model User you'd choose the attribute in the second key field
type User
#model
#key(fields: ["id", "DoB"]) {
id: ID!
name: String!
DoB: String!
createdAt: String!
}
and a query would sort the items by their DoB

Refresh Tokens in MongoDB

What is the best solution to remove a refresh token from MongoDB automatically.
On login the user is given a temporary auth token which lasts 30 seconds. They are also given a permanent token, stored in MongoDB, which currently lasts until they log out.
I want to remove the permanent one at the end of every day, but I'm not sure how to do that without having a cron job running (to monitor what time it is). This seems a bit complex for such a small task. Is there a way mongo would know what the time is and then remove the refresh token?
This is how the token collection looks:
Thank you
To auto-delete the MongoDB documents after some time, you should use the TTL(time to live) collection feature documented here.
Essentially, you need to create an index on the collection that stores the token documents. For your use case, you can do something like this:
// This would delete the tokens document after 3600seconds after creation
// You can tweak the time as you wish.
db.tokens.createIndex({ "createdAt": 1 }, { expireAfterSeconds: 3600 });
NodeJS, mongodb.
Just simply create a model for each token.
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const tokenSchema = new Schema({
_userId: {
type: Schema.Types.ObjectId,
required: true,
ref: 'user'
},
token: {
type: String,
required: true
},
expireAt: {
type: Date,
default: Date.now,
index: { expires: 60*60*24 }
}
})
module.exports = mongoose.model('tokens', tokenSchema)

group and collect document based on field in mongodb

I have notifications collection with this schema
_const notificationsSchema = new Schema({
_from: {
type: Schema.ObjectId, ref: 'User',
},
_to: {
type: Schema.ObjectId, ref: 'User',
},
_target: String,
type: {
type: String,
},
createdAt: {
type: Date,
default: Date.now,
},
});
How to group notifications like facebook " and 50 others liked your post"?
How to retrieve this shape of data, for the documents that has same _parent?
[
{
_id: "",
_to: "",
_parent: "",
lastThreeUsers: [_ from, ...],
count: 50
}
]
This is a very open ended response. There is no one right answer. I have provided both a naive and ideal approach to the problem. You may think of another, better way.
You would need to have a something along the lines of a "Likes" collection where you store all likes from users where each like has a reference to the post being liked. Then you would have to perform an aggregation on the likes collection to get all the likes where the postId is equal to the id of the post you want total likes for.
First attempt that.
Then a better, "real world" approach is to also add a "likesCount" (call it what you want) property onto Post documents that keeps tracks of the likes on the post. Update the likesCount each time a user likes/dislikes that post. This way you won't actually have to search through the "Likes" collection over and over again everytime your have to show that data.

Sequelize: Change "validate" meta data of column

Is it possible to change the "validate" meta data of a column using a migration file? I tried the queryInterface.changeColumn method and it seems like it can only change the three meta data mentioned in the docs (defaultValue, allowNull, and type).
I've tried doing something like this inside the 'up' object of the migration file:
queryInterface.changeColumn(
'tableName',
'columnName',
{
validate: {
is: /new_regex_validation/
}
}
)
However, the above attempt did not work for me when I ran "sequelize db:migrate"
For simplicity's sake, I'll use a table definition to elaborate on my question:
I'm trying to change an already existing table like this:
var tableName = sequelize.define('tableName', {
columnName: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
validate: {
is: /some_regex_validation/
}
}
})
into this using sequelize migration:
var tableName = sequelize.define('tableName', {
columnName: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
validate: {
is: /a_new-or-different_regex_validation/
}
}
})
or simply remove the validate meta data while using sequelize migration:
var tableName = sequelize.define('tableName', {
columnName: {
type: DataTypes.STRING,
unique: true,
allowNull: false
}
})
Any ideas?
Validation happens on the client, not on the database. You don't need a migration for it.
I came across this question a few times trying to understand the difference between building my model with validations and using migrations.
I found this link very helpful. Hopefully someone else does in the future.
Difference between Validations and Constraints
Validations are checks performed in the Sequelize level, in pure
JavaScript. They can be arbitrarily complex if you provide a custom
validator function, or can be one of the built-in validators offered
by Sequelize. If a validation fails, no SQL query will be sent to the
database at all.
On the other hand, constraints are rules defined at SQL level. The
most basic example of constraint is an Unique Constraint. If a
constraint check fails, an error will be thrown by the database and
Sequelize will forward this error to JavaScript (in this example,
throwing a SequelizeUniqueConstraintError). Note that in this case,
the SQL query was performed, unlike the case for validations.
https://sequelize.org/master/manual/validations-and-constraints.html

Categories