inner join in JayData - inner-join

I use JayData liberary and I want to know that it is possible to simulate inner join in JayData, like:
Customers inner join Orders on
Customers.CustomerID = Orders.CustomerID
and how it could be possible?

AdHoc joins in general are not yet supported by JayData in the current release. It's on the roadmap though.
It is however possible to achieve similar behavior on a number of ways, depending on your needs and the underlying data provider. I assume you are using the OData provider.
In this case you can use navigation properties to represent the relation and thus achieve an implicit join on queryies.
Entity and context definition:
$data.Entity.extend("Customer", {
Id: { key: true, computed: true, type: 'int' },
Name: { type:string },
Orders: { type: $data.EntitySet, elementType: 'Order', inverseProperty: 'Customer' }
});
$data.Entity.extend("Order" {
Id: { key: true, computed: true, type: 'int' },
Customer: { type: Customer, inverseProperty: 'Orders' }
});
$data.EntityCotnext.extend("CustomerOrders", {
Customers: { type: $data.EntitySet, elementType: Customer },
Orders: { type: $Data.EntitySet, elementType: Order }
});
1) query orders by customer:
context.Orders.filter( function(order) {
return order.Customer.Name.startsWith('John');
}).toArray(...)
2) query customer by orders: this is new feature released in JayData 1.1 (make sure to update your files)
ordersQuery = context.Orders.filter( function(order) { return order.Value > 200 });
context.Customers.filter( function(customer) {
return custom.Orders.some(ordersQuery);
}).toArray(...);

Related

Achieve a transitive association for a query in SailsJS

My question might be an obvious one, however i've been struggling with this one for a couple of nights. Here's a basic overview of my problem.
I have the following three models:
Model 1
/* api/models/Parent.js */
module.exports = {
tableName: "table1",
attributes: {
name: {
type: "string",
},
children: {
collection: "child",
via: "parentId"
},
},
};
Model 2
/* api/models/Child.js */
module.exports = {
tableName: "table2",
attributes: {
name: {
type: "string",
},
parentId: {
model: "parent"
},
vaccinations: {
collection: "vaccination",
via: "childId"
},
},
};
Model 3
/* api/models/Result.js */
module.exports = {
tableName: "table3",
attributes: {
name: {
type: "string",
},
childId: {
model: "child"
},
vaccinationId: {
model: "vaccination"
},
},
};
I wish to be able to query the following
GET /vaccination?parentId=1 which will retrieve all vaccinations for children that have parentId=1. I am not sure what's the best practice to follow here, i would really appreciate any help. I have read the Through Associations but for some reason, i can not get it to work.
Thanks in advance.
Following query might help you here:
let children = await Child.find({
parentId: 1
})
.populate('parentId')
.populate('vaccinations');

Apollo GraphQl model attribute is not accessing object in ReactJs

I am implementing category and subcategory display in ReactJs using Apollo GraphQl Query.
I tried to using same table as category with fields.
id,
category_name,
category_img,
category_parent_id ( id from same table),
category_status,
typeDefs and resolver are belows
Category.js
const typeDefs = gql`
extend type Query {
getSingleCategory(id: ID): allCategory
}
`;
type allCategory {
id: ID!
category_name: String
category_img: String
category_parent_id: Int
category_status: Status
}
const resolvers = {
Query: {
getSingleCategory: async (parent, args, context, info) => {
var data = await db.category.findOne({
where: {
id: args.id,
},
include: [
{
model: db.category,
as: "children",
attributes: [["category_name", "children_name"]],
nested: true,
required: false,
},
],
required: false,
});
return data;
},
},
},
Model in GraphQl
module.exports = function (sequelize, DataTypes) {
var category = sequelize.define(
"category",
{
id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
category_name: {
type: DataTypes.STRING(256),
allowNull: false,
},
category_img: {
type: DataTypes.STRING(256),
allowNull: false,
},
category_parent_id: {
type: DataTypes.INTEGER(10).UNSIGNED,
allowNull: false,
references: {
// WorkingDays hasMany Users n:n
model: "category",
key: "children",
},
},
category_status: {
type: DataTypes.ENUM("Acitve", "Inactive"),
allowNull: false,
},
},
{
tableName: "category",
timestamps: false,
}
);
category.associate = function (models) {
models.category.belongsTo(models.category, {
onDelete: "CASCADE",
foreignKey: "category_parent_id",
as: "children",
targetKey: "id",
});
};
return category;
};
In ReactJs
category.ts
export const GET_CATEGORYBY_ID = gql`
query($catId: ID!) {
getSingleCategory(id: $catId) {
id
category_name
category_img
category_parent_id
category_status
}
}
`;
I am trying to accessing {data.getSingleCategory} , I got all parameters but not able to get children_name from same table as parent_name.
Anyone can tell me what is the issue I am not able to access that children_name as attribute from same table Or there any other way so that we can access category/subcategory from same table and display it to reactjs template.
Not defined [separately] in types, not used/defined [as 'children' property?] in parent type, not requested in query ... simply filtered out from response.

How to run a RANK() function on a model

How can I run a rank function to generate an attribute on a given sequelize model?
For example, given the model:
Players.init(
{
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: false
},
rating: type: DataTypes.FLOAT
},
{ sequelize }
)
I would like to get an attribute rank when running Players.getAll({ rank: rating }). This would generate SQL similar to:
SELECT id, rating, RANK() OVER (ORDER BY rating DESC) as rank FROM players
How would I do this using sequelize?
You can use Sequelize Literal Function like follows -
attributes: [
'id', 'rating',
[Sequelize.literal('(RANK() OVER (ORDER BY rating DESC))'), 'rank']
]
to create new attributes.

Referencing a composite primary key in a Sequelize.js seed model

Is it possible to reference composite primary keys in Sequelize?
I'm working on a web-app that helps organize kitchen waste. The restaurant organizes its weeks and months into 'periods' where the first week of September would be '9.1'. For every period, I need to create a new batch of ingredient objects that can keep track of what their prices and quantities were for that period. I figure it would be best to make the period primary keys their combined month and week, as that will be unique in the database.
I may add year on later, but that doesn't change my problem.
The database I'm working with is Postgres.
This is my period table model in my sequelize seed file:
.then(() => queryInterface.createTable('periods', {
month: {
type: Sequelize.INTEGER,
validate: {
max: 12,
min: 1
},
unique: "monthWeekConstraint",
primaryKey: true
},
week: {
type: Sequelize.INTEGER,
validate: {
max: 4,
min: 1
},
unique: "monthWeekConstraint",
primaryKey: true
},
createdAt: {
type: Sequelize.DATE
},
updtedAt: {
type: Sequelize.DATE
}
}))
I'd like to reference the periods stored in the above table in my periodItems table, which I have (incorrectly) looking like:
.then(() => queryInterface.createTable('periodItems', {
periodMonth: {
type: Sequelize.INTEGER,
references: {model: 'periods', key: 'monthWeekConstraint'}
},
periodWeek: {
type: Sequelize.INTEGER,
references: {model: 'periods', key: 'monthWeekConstraint'}
},
day: {
type: Sequelize.INTEGER,
validate: {
min: 1,
max: 7
}
},
...other irrelevant fields...
}))
I'm definitely new to databases, so I apologize if I'm way off. I've gotten a few other tables doing what I'd like, but I've been stuck on this problem for a few days.
While it is possible to create composite primary keys in Sequelize by specifying primaryKey: true against more than one column (as you have already done above), Sequelize doesn't currently support composite foreign keys, so there is no way to reference a model/table which has composite primary keys.
See https://github.com/sequelize/sequelize/issues/311 for a discussion on the subject.
model/product.js:
const Product = sequelize.define("product", {
sku: { type: Sequelize.STRING, allowNull: false, primaryKey: true },
title: { type: Sequelize.STRING, allowNull: false },
availability: {
type: Sequelize.STRING,
allowNull: false,
defaultValue: false,
}
});
model/Attribute.js:
const Attribute = sequelize.define("attribute", {
key: { type: Sequelize.STRING, allowNull: false, primaryKey: true },
productSku: { type: Sequelize.STRING, allowNull: false, primaryKey: true },
value: { type: Sequelize.STRING, allowNull: false },
});
After importing to app.js:
product.hasMany(attribute, { foreignKey: "productSku", sourceKey: "sku" });
attribute.belongsTo(product, { foreignKey: "productSku", targetKey: "sku" });
Explanation:
Product.sku is exported as foreign key to Attibute.productSku. Attribute table has a composite foreign (key + productSku), and a ForeignKey(productSku) from product.sku;

How to associate tables via id

How can I associate two tables in Sequelize? I tried belongsTo, but this doesn't work. Example:
First table:
users = sequelize.define('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: Sequelize.TEXT,
type: Sequelize.INTEGER
Second table:
profiles = sequelize.define('profiles', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
place: Sequelize.TEXT,
phone: Sequelize.INTEGER
Association:
profiles.belongsTo(users, {foreignKey: 'id'});
Request:
users.findOne({
where: {name: 'John'},
include: [{model: db.tables.profiles}]
}).then(function(user_data) {
console.log(user_data);
})
Returned [Error: profiles is not associated to users!]
I need to return the matched line of "users" and the line with the same id from the table 'profiles'. Where is the mistake?
You need to declare the association for both tables. From your schema I can't tell what the join condition is. If your profiles table also has a column user_id such that profiles.user_id = users.id, then you could say the following:
users.hasMany(profiles, {
foreignKey: 'id'
});
profiles.belongsTo(users, {
foreignKey: 'user_id'
});

Resources