sequelize : Create new entry with existing foreign key - node.js

I create 2 models :
userPreferenceCategories = sequelize.define("userPreferenceCategories", {
id : {
type : Sequelize.INTEGER,
autoIncrement : true,
primaryKey : true,
allowNull : false
},
name : {
type : Sequelize.STRING,
allowNull : false
}
}, {
indexes: [
{
unique : true,
fields : ["name"]
}
],
freezeTableName : true
});
and
userPreferenceCategoryTypes = sequelize.define("userPreferenceCategoryTypes", {
id : {
type : Sequelize.INTEGER,
autoIncrement : true,
primaryKey : true,
allowNull : false
},
name : {
type : Sequelize.STRING,
allowNull : false
}
}, {
indexes: [
{
unique : true,
fields : ["name", "userPreferenceCategoryId"]
}
],
freezeTableName : true
});
With relation :
userPreferenceCategoryTypes.belongsTo(userPreferenceCategories, {
onDelete : "cascade",
onUpdate : "cascade",
foreignKey : {
field : "userPreferenceCategoryId",
allowNull : false,
}
});
one time, I create an userPreferenceCategories entry :
userPreferenceCategories.upsert({name : "cat1"});
in second time, I would like create an userPreferenceCategoryTypes associate at "cat1" like this :
userPreferenceCategoryTypes.upsert({
name : "type1",
userPreferenceCategory : {
name : "cat1"
}
}, {
include: [ {
model : userPreferenceCategories
} ]
});
but this don't work with message :
Unhandled rejection SequelizeValidationError: notNull Violation: userPreferenceCategoryId cannot be null
In fact, sequelize does not seem to add userPreferenceCategoyId attribut on sql request. How can I insert new entry in userPreferenceCategoryTypes this foreignKey of cat ? I don't execute that on series.
EDIT 1 :
I found a solution but I'm not sure if there had better : /
userPreferenceCategory.find({where: {name: "cat1"}}).then(function (cat) {
UserPreferenceCategoryType.create({
name : "type1",
userPreferenceCategoryId : cat.getDataValue("id")
});
});

It seems it's the only solution
No, because when you do a create with include, it will create the
associated instance, not associate it.

Related

How to improve mongoDb query performance?

I have a collection named Codes. This is how the Schema is defined:
import mongoose from 'mongoose'
import autoIncrement from 'mongoose-auto-increment';
const Schema = mongoose.Schema;
const CodesSchema = mongoose.Schema(
{
configId: { type: Number },
campaignId: { type: Number },
permissions: {
all: { type: Boolean, default: false },
users: { type: [Number], default: [] }
}
)
autoIncrement.initialize(mongoose.connection);
CodesSchema.plugin(autoIncrement.plugin, { model: 'Codes', field: 'campaignId' });
export default mongoose.model('Codes', CodesSchema)
There is one query that looks like this:
const query = {
$and:[
{$or: [
{'permissions.all': true},
{'permissions.users': 12}
]},
{configId: 3}
]
};
Codes.find(query, (err, res) => {
// do something with the result
})
This works fine, but if there is a huge number of documents in the database then this query is really slow.
Is there anything I can do to improve the performance of this specific query? I'm thinking that createIndex would help, but I'm not sure if that can be applied since there are $and and $or conditions.
UPDATE
I've added indexes this way:
CodesSchema.index({configId: 1, 'permissions.all': 1, 'permissions.users': 1});
But running the query with .explain('executionStats') option returns:
{
"executionSuccess" : true,
"nReturned" : 6,
"executionTimeMillis" : 0,
"totalKeysExamined" : 10,
"totalDocsExamined" : 10,
}
Which doesn't seems right because the number of docs examined is greater than the number of docs returned.
The index itself is correct.
It must be CodesSchema.index, not Code.index.
Ensure you call Code.syncIndexes to update indexes dbside.
The "explain" part - you should check winningPlan.
If no indexes are used by the query, it should be something like
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
When the index is being used it changes to
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "OR",
"inputStages" : [
{
"stage" : "IXSCAN",
"keyPattern" : {

in node(sails framework) we are getting model name is not defined

In our web app we are getting model name is not defined. In model i have define following properties
module.exports ={
schema:'true',
autoPK: false,
autoCreatedAt: false,
autoUpdatedAt: false,
tablename : 'outlet_cuisine',
attributes: {
outlet_cuisine_id : {type:'int',primaryKey: true,autoIncrement: true},
outlet_id : {type : 'int', model: "outlet"},
cuisine_id : {type : 'int', model : "cuisine"}
}
};
And in controller i am using following command
Following code for controller:
outlet_cuisine.destroy({'outlet_id' : outlet_id},
function deastrires(err) {
});
issue in case sensitive. I am getting outlet_cuisine is not defined.

Sequelize.js - Persist model with association

I'm trying to save an entity with the following models and save method but it only creates the parent entity. See:
var Project = database.define('projects', {
name : {
type : Sequelize.STRING,
allowNull : false,
unique : true
},
archived : {
type : Sequelize.BOOLEAN,
allowNull : false,
defaultValue : false
}
});
var Sprint = database.define('sprints', {
name : {
type : Sequelize.STRING,
allowNull : false,
unique : true
},
start : {
type : Sequelize.DATE
},
end : {
type : Sequelize.DATE
}
});
Project.hasMany(Sprint, {
as : 'sprints'
});
Sprint.belongsTo(Project);
The save method in Express:
var project = req.body;
models.Project.create(project).then(function(project){
return res.json(project);
}, function(err) {
return next(err);
});
The req.body is something like:
{
archived : false,
name : "Projeto 1",
sprints : [{
end : "2016-02-25T03:00:00.000Z",
name : "Sprint 1",
start : "2016-02-19T02:00:00.000Z"
}
]
}
The result is one record of Project created in database. Nothing more.
Sprint entry is also new, I was expecting it could be created together with Project.
Any ideas?
Thanks
Ok, now it saves Project and it's Sprints:
var project = req.body;
models.Project.create(project, {
include : [{
model : models.Sprint,
as : 'sprints'
}
]
}).then(function (project) {
return res.json(project);
}, function (err) {
return next(err);
});

meteor-collection2 schema crash Accounts.createUser()

I'm trying to use meteor-collection2 to validate my collection.
I have a service, on server side :
Meteor.methods
UserSignUpService: (options) ->
# create user
Accounts.createUser options
That I call on client side :
Meteor.call 'UserSignUpService',
email: 'my.email#domain.com'
password: 'mypassword'
profile:
name: 'me'
And this is my schema :
# user profile
UserProfile = new SimpleSchema
name:
type: String
min: 1
max: 50
optional: false
# user
User = new SimpleSchema
emails:
type: [Object]
optional: false
"emails.$.address":
type: String
regEx: SimpleSchema.RegEx.Email
"emails.$.verified"
type: Boolean
createdAt:
type: Date
profile:
type: UserProfile
optional: false
services:
type: Object
optional: true
blackbox: true
# links to user collection
Meteor.users.attachSchema User
But, when user is created, there are not all fields in my mongo collection :
{ "_id" : "ikvBq95JBLXMCSnhT", "emails" : [ { "address" : "my.email#domain.com" } ] }
Whereas it should be :
{ "_id" : "WNkjGFhNkLpRR2Jex", "createdAt" : ISODate("2015-08-06T09:00:59.887Z"), "services" : { "password" : { "bcrypt" : "$2a$10$QvMLuI.Pv0bzzii3ZZP...fHfUlU9KiYfcsC2VHBf6q1OSPM6cfTW" }, "resume" : { "loginTokens" : [ { "when" : ISODate("2015-08-06T09:01:00.002Z"), "hashedToken" : "9KyqjRVSWm0nfIlS0sqODRmddlJ5GaG3mJ4+RMItOhk=" } ] } }, "emails" : [ { "address" : "my.email#domain.com", "verified" : false } ], "profile" : { "name" : "me" } }
Any idea on this problem ?
Many Thanks !
You're not actually setting the createdAt field value, try:
createdAt:
type: Date
autoValue: function(){
if this.isInsert return new Date()
else if this.isUpsert return { $setOnInsert: new Date };
else if this.isSet this.unset();
}
You can also omit optional: false in your schema since that's the default.
Also, and I suspect this is the bigger problem, not all user keys are returned to the client by default, only profile is normally published. For example you're expecting the services key but that doesn't normally come across. Look at the document in the mongo console and see what's there. You might need to publish a more comprehensive set of keys to the client.

Sails 0.10 & Many-to-Many association - Get all associated data, not the first only

I have 2 models with a Many-to-Many association. My code to associate these two models is working well (it create a new collection item_languages__language_items with the corresponding documents inside). But then I have trouble to get all the associated data (languages) of a specific item. I'm using MongoDB.
// Item.js
module.exports = {
schema: true,
autoPK: false,
attributes: {
uuid: {
type: 'string',
primaryKey: true,
unique: true,
required: true,
uuidv4: true
},
languages: {
collection: 'language',
via: 'items',
dominant: true
}
}
}
// Language.js
module.exports = {
schema: true,
autoPK: false,
attributes: {
code: {
type: 'string',
primaryKey: true,
required: true,
minLength: 2,
maxLength: 2,
unique: true
},
items: {
collection: 'item',
via: 'languages'
}
}
}
Data stored in the item_languages__language_items collection:
/* 0 */
{
"language_items" : "es",
"item_languages" : "69e4f3a3-1247-4a06-ae2d-9df27ac9495b",
"_id" : ObjectId("5330bcebf8e0b61509c771d5")
}
/* 1 */
{
"language_items" : "fr",
"item_languages" : "69e4f3a3-1247-4a06-ae2d-9df27ac9495b",
"_id" : ObjectId("5330bd26f8e0b61509c771d6")
}
/* 2 */
{
"language_items" : "en",
"item_languages" : "69e4f3a3-1247-4a06-ae2d-9df27ac9495b",
"_id" : ObjectId("5330bedcc076355b09da3ccd")
}
Now in my ItemController.js, I want to get a specific item with all associated languages:
Item
.findOne({uuid: '69e4f3a3-1247-4a06-ae2d-9df27ac9495b'})
.populate('languages')
.exec(function (e, r) {
console.log(r.toJSON());
});
But here I get my item with only 1 associated language, when I expected to get the 3 associated languages.
This appears to be a bug in the current beta implementation of sails-mongo which keeps populate from working properly with custom-defined keys. Please post this to the sails-mongo issues forum! In the meantime the only solution appears to be to use the default MongoDB primary keys.

Resources