Problem ordering sequelize query by date, in ascending order - javascript

I need to order a sequelize query by date ascending. What I'm trying to sort out is the result of the model: ExamScore (as student_score).
Note that in the ordering I am setting the column "updated_at" and the way of ordering. However, it is not working, it simply does not order.
const students = await Students.findAll({
attributes: ['id', 'name', 'cpf'],
include: [
{
model: Status,
attributes: ['status', 'updated_at'],
as: 'student_status',
where: [{ course_id }],
required: false,
},
{
model: ExamScore,
attributes: ['score', 'updated_at'],
as: 'student_score',
where: [{ module_id }],
required: false,
order: [['updated_at', 'ASC']],
},
],
});
Below is an example of the return from this query:
{
"id": 30014,
"name": "Jon Doe",
"cpf": "xxxxxxxx",
"student_status": [
{
"status": "APROVADO",
"updated_at": "2021-05-27T03:06:14.502Z"
}
],
"student_score": [
{
"score": "9.00",
"updated_at": "2021-05-27T03:06:13.998Z"
},
{
"score": "2.00",
"updated_at": "2021-05-27T02:59:22.571Z"
}
]
},
I can't understand what I'm doing wrong.

Try adding order to your top query, not inside includes.
Example:
const students = await Students.findAll({
attributes: ['id', 'name', 'cpf'],
include: [
{
model: Status,
attributes: ['status', 'updated_at'],
as: 'student_status',
where: [{ course_id }],
required: false,
},
{
model: ExamScore,
attributes: ['score', 'updated_at'],
as: 'student_score',
where: [{ module_id }],
required: false,
},
],
// add the order, model ExamScore with alias student_score
order: [[{ model: ExamScore, as: 'student_score' }, 'updated_at', 'ASC']],
});

Related

Fetching data with One to Many/Many to One and Many to Many in TypeORM using javascript

Hi i'am having a problem fetching my data with a profile, kids and toys, which the profile is the parent of the kids and kids is the parent of the toys. I already created fetching the data with "one to many" and "many to one" of profile and kids. Now i want the toys be in the kids attribute.
Here's my table looks like..
Here's my entities..
ProfileEntity.js
var {EntitySchema} = require("typeorm")
module.exports = new EntitySchema({
name "Profile",
tableName: "profile",
columns: {
profile_id: {
primary: true,
type: "integer"
},
name: {
type: "varchar"
},
age: {
type: "integer"
}
},
relations: {
kids: {
target: "Kids",
type: "one-to-many",
inverseSide: "profile"
}
}
});
KidsEntity.js
var {EntitySchema} = require("typeorm")
module.exports = new EntitySchema({
name "Kids",
tableName: "kid",
columns: {
kid_id: {
primary: true,
type: "integer",
},
profile_id: {
primary: true,
type: "integer"
},
kid_name: {
type: "varchar"
},
age: {
type: "integer"
}
},
relations: {
profile: {
target: "Profile",
type: "many-to-one",
joinColumn: {
name: "profile_id"
}
}
}
});
now when i call the
const data = await connection.getRepository("Profile").find({
where: {
name: "Doe"
},
relations: {
kids: true
}
});
it gives me an array like this which is correct
[
{
"profile_id": 1,
"name": "Doe",
"age": 28,
"kids": [
{
"kid_id": 1,
"profile_id": 1,
"kid_name": "Coco",
"age": 2
},
{
"kid_id": 2,
"profile_id": 1,
"kid_name": "Melon",
"age": 3
}
]
}
]
Now i want the Toys data be inside the kids attribute like this.
[
{
"profile_id": 1,
"name": "Doe",
"age": 28,
"kids": [
{
"kid_id": 1,
"profile_id": 1,
"kid_name": "Coco",
"age": 2
"toys": [
{
"toy_id": 1,
"kid_id": 1,
"toy_name": "Golf Set",
"for": "2-3"
},
{
"toy_id": 2,
"kid_id": 1,
"toy_name": "Trucks",
"for": "2-3"
},
]
},
{
"kid_id": 2,
"profile_id": 1,
"kid_name": "Melon",
"age": 3,
"toys": [
{
"toy_id": 3,
"kid_id": 2,
"toy_name": "Barbie",
"for": "3-5"
}
]
}
]
}
]
How can i fetch the data like this? thanks in advance.
It appears that according to your data structure, it is nested relations you are after, not "many-to-many" relations. If you actually wanted many-to-many, then you could have defined a separate "toys" table and then something like "kids_toys" table that establishes a connection between "kids" and "toys".
But for now, following your current setup. First, you can define relations for "toys" like you did for "kids":
module.exports = new EntitySchema({
name "Kids",
...
relations: {
profile: {
...
},
toys: {
target: "Toys",
type: "one-to-many",
inverseSide: "kid"
}
}
Then add definition for the Toys table itself (add other fields properly to Toys.js):
module.exports = new EntitySchema({
name "Toys",
columns: {
toy_id: {
primary: true,
type: "integer",
},
kid_id: {
type: "integer"
},
...
}
...
relations: {
kid: {
target: "Kids",
type: "many-to-one",
joinColumn: {
name: "kid_id"
}
}
}
And finally do the nested query:
const data = await manager.getRepository("Profile").find({
where: {
name: "Doe"
},
relations: {
kids: {
toys: true
}
}
});
Please note that typeorm targets typescript primarily, it's so much easier to work with it in typescript (much less to write). Not sure, why you are defining your entities using plain javascript with typeorm?

How to get Associated model row count in Sequelize?

Hi I have a following code. From this I need a total rows count from the Comment Model. Can you please help? Thanks in Advance!
Post.hasMany(models.Comment, {
as: 'postComment',
foreignKey: 'postId',
});
Comment.belongsTo(models.Post, {
foreignKey: 'postId',
as: 'post',
});
return Post.findAndCountAll({
attributes: [['postId', 'id'], 'target_population', 'title', ['type', 'category'], 'stage', ['text_content', 'comment'], ['time_posted', 'engagement_timeframe'], ['closing_date', 'engagement_completion'], ['engagement_end', 'engagement_close'], ['non_constituent_view', 'non_constituents'], ['discussion_board_enabled', 'discussion_board'], 'attached_documents', 'description'],
where: where,
offset: offset,
limit: limit,
distinct: true,
include: [
{
model: Survey,
as: 'survey',
attributes: ['isOpen'],
where: {isOpen: "TRUE"},
required: false,
include: [
{
model: Question,
as: 'question',
include: [
{
model: ProposedAnswer,
as: 'choice',
attributes: [['proposedAnswerId', 'id'], ['answer', 'value']],
required: false,
}
],
attributes: [['questionId', 'id'], ['question', 'title'], ['questionType', 'type']]
}
]
},
{
model: User,
as: 'user',
attributes: ['first_name'],
where: {userId: {[Op.not]: null}},
},
{
model: Topic,
as: 'topic',
attributes: [['topicId', 'id'], ['name', 'value']],
through: {attributes: []},
},
{
model: Comment,
as: 'postComment',
},
],
order: [
['postId', 'DESC'],
]
})

MongoDB check if a key exists and has a specific value

I'm absolute beginner in MongoDB and I have a problem which I can't solve.
I have a Request collection which looks like this:
{ ->document one
id...
Category:[Car]
Color:[Black,White]
Fuel Type:[Diesel, Gasoline]
}
{ ->document two
id..
Category:[Car]
}
I have a Product object in JavaScript which looks like this:
let newObj: {
Category: 'Car',
Model: 'BMW',
'Production age': 1997,
'Fuel Type': 'Diesel',
Color: 'White',
'Mileage (km)': '75213',
Price: '9000',
Electric: 'Yes',
'Mile range': '300'
}
I want to get all documents from Request collection which contains one of the keys and a specific value. To understand better:
In my case the Category=Car and the Color=White so I want to return back both of the documents.
If the Category=Car but the Color=Red I want to return only the second document
If the other fields doesn't exists I don't care about them only about the matched ones.
let findArgs={}
for (const [key, value] of Object.entries(product.newObj)) {
filterArgs[key]={$exists: true,$in:[value]}
}
let result= await requestColl.aggregate([
{$match: filterArgs },
{$sort: {[sortBy]:order}},
]).toArray();
This is the filterArgs query which will be in {match:}
{
Category: { '$exists': true, '$in': [ 'Car' ] },
Model: { '$exists': true, '$in': [ 'BMW' ] },
'Production age': { '$exists': true, '$in': [ 1997 ] },
'Fuel Type': { '$exists': true, '$in': [ 'Diesel' ] },
Color: { '$exists': true, '$in': [ 'White' ] },
'Mileage (km)': { '$exists': true, '$in': [ '75213' ] },
Electric: { '$exists': true, '$in': [ 'Yes' ] },
'Mile range': { '$exists': true, '$in': [ '300' ] }
}
How can I acheive the above mentioned? Thanks in advance.
UPDATE
I tried to do a query like this but still due to that Car exists in both documents I can't get the specific one.
{ $or:
[ { $and: [{ Category: { '$in': [ 'Car' ]}}]},
{ $and: [ { Category: { '$in': [ 'Car' ]}}, { Color: { '$in': [ 'White' ] }}]}
]}

Mongoose populate virtuals - exclude localField and foreignField from the query results if foreignField is null or an empty array

I have a simple question.
In Mongoose I have two models. One is for Leagues and the other one is for Fixtures. Each league has a unique id, and each fixture is related to a league with it's key of league_id.
In the Leagues schema I have also defined a virtual called fixtures.
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const LeagueSchema = new Schema(
{
_id: { type: mongoose.Schema.Types.ObjectId, select: false, auto: true },
id: { type: Number, required: true, unique: true, index: true },
name: { type: String, required: true },
}
);
LeagueSchema.virtual('fixtures', {
ref: 'fixtures',
localField: 'id',
foreignField: 'league_id',
justOne: false,
});
const Leagues = mongoose.model('leagues', LeagueSchema);
const FixtureSchema = new Schema(
{
_id: { type: mongoose.Schema.Types.ObjectId, select: false },
match_id: { type: Number, required: true, index: true, unique: true },
league_id: { type: Number, required: true },
league_name: { type: String, required: true },
timestamp: { type: Number, required: true, index: true },
}
);
const Fixtures = mongoose.model('fixtures', FixtureSchema);
Here is the problem. The list of all leagues is very big and not all of them will always have fixtures that match the .populate() so I want to exclude them from my query.
For example, if I don't want any fixtures older than a given timestamp, I will do the following:
(async () => {
const target_time = 1568851200000;
const leagues = await Leagues
.find({})
.populate({ path: 'fixtures', match: { timestamp: { $gte: target_time } } })
.lean();
console.log(leagues);
})();
What this does is it filters out the fixtures by timestamp correctly, but it does not exclude Leagues without fixtures from the query.
Here is what this query returns:
Current result:
[
{
id: 2,
name: 'Champions League',
fixtures: []
},
{
id: 5,
name: 'Europa League',
fixtures: [
[Object],
[Object],
[Object],
[Object],
]
},
{
id: 8,
name: 'Premier League',
fixtures: []
}
];
And here is what I want to achieve:
Desired result:
[
{
id: 5,
name: 'Europa League',
fixtures: [
[Object],
[Object],
[Object],
[Object],
]
},
];
I am aware that I can do something like leagues.filter(item => item.fixtures.length > 0), but this query is going to be called tens of times each second, I'm afraid that running another filter after the query can lead to performance issues.
Any help or possible alternatives are appreciated.

Sencha Touch2: Display nested Json data in seperate row in list

I am new to sencha touch2, facing problem while displaying nested json data in seperate rows in list.
Here is my Json looks like:
[
{
"work": {
"agent": {
"activeFlag": "false",
"shiftId": "0",
"id": "0",
"deleteFlag": "false"
},
"id": "124",
"status": "Unassigned",
"assignment": {
"pnr": {
"locator": "ABCDEF",
"connectTime": "0",
"id": "0"
},
"id": "123",
"alerts": "Delay",
"customers": [
{
"lastName": "XYZ",
"firstName": "MNO"
},
{
"lastName": "PQR",
"firstName": "STU "
}
]
}
}
},
{
"work": {
"agent": {
"activeFlag": "false",
"shiftId": "0",
"id": "0",
"deleteFlag": "false"
},
"id": "124",
"status": "Unassigned",
"assignment": {
"pnr": {
"locator": "ABCDEF",
"connectTime": "0",
"id": "0"
},
"id": "123",
"alerts": "Delay",
"customers": [
{
"lastName": "ANY",
"firstName": "KLJ"
},
{
"lastName": "CHE",
"firstName": "MAK"
}
]
}
}
}
]
like this i have 30 'work' objects and in 1 'work' i have 1 'customers' array and i have multiple customers inside
I want to show 'customers' in seperate rows in list but am able to show all the customers of single 'work' in one row like.
Output should be:
---------------
delay
First Name: MNO
---------------
delay
First Name: STU
---------------
delay
First Name: KLJ
---------------
delay
First Name: MAK
---------------
here are models.
ModelList.js:
Ext.define('CustomList.model.ModelList', {
extend: 'Ext.data.Model',
xtype:'modelList',
requires:['CustomList.model.Customers'],
config: {
fields:['work'],
proxy:{
type:'ajax',
url:'http://localhost:9091/CustomListJson/app/store/sample.json',
reader:{
type:'json'
}
},
hasMany:{model:'CustomList.model.Customers',
name:'customers'}
}
});
Customers.js:
Ext.define('CustomList.model.Customers', {
extend: 'Ext.data.Model',
config: {
fields: [
'firstName','lastName'
],
belongsTo: "CustomList.model.ModelList"
}
});
Here is my ShowList.js:
Ext.define('CustomList.view.ShowList',{
extend:'Ext.Panel',
xtype:'showList',
config:{
layout:'fit',
styleHtmlContent:'true',
styleHtmlCls:'showListCls',
items:[
{
xtype:'list',
id: 'listitems',
store:'StoreList',
itemTpl:[ '{work.assignment.alerts}<br>',
'<tpl for="work.assignment.customers">',
'firstName: {firstName}<br>',
'</tpl>'
]
// am able get the below values in list
// itemTpl:'{work.assignment.alerts}'
// itemTpl:'{work.assignment.pnr.locator}'
// itemTpl:'{work.agent.activeFlag}'
// itemTpl: '<b>{firstName} {lastName} </b><br>'+'pnr: '+ '{locator} <br>' +
// 'Alerts: '+'{alerts}' +'status: '+'{status} '
}]
}
});
Here is my StoreList.js:
Ext.define('CustomList.store.StoreList', {
extend:'Ext.data.Store',
requires:['Ext.data.reader.Json'],
config:{
model:'CustomList.model.ModelList',
autoLoad:'true'
}
});
Can anyone please help me. Thanks.
Is this what you were after?
download here
This is a really simple mock up but it should help you out, I think you're model associations are confusing things.
List:
Ext.define('MyApp.view.MyList', {
extend: 'Ext.dataview.List',
config: {
store: 'MyJsonStore',
itemTpl: [
'<div><div><h1>{work.assignment.alerts}</h1></div><tpl for="work.assignment.customers"><div>First Name: {firstName}</div></tpl></div>'
]
}
});
store:
Ext.define('MyApp.store.MyJsonStore', {
extend: 'Ext.data.Store',
config: {
data: [
{
work: {
agent: {
activeFlag: 'false',
shiftId: '0',
id: '0',
deleteFlag: 'false'
},
id: '124',
status: 'Unassigned',
assignment: {
pnr: {
locator: 'ABCDEF',
connectTime: '0',
id: '0'
},
id: '123',
alerts: 'Delay',
customers: [
{
lastName: 'XYZ',
firstName: 'MNO'
},
{
lastName: 'PQR',
firstName: 'STU '
}
]
}
}
},
{
work: {
agent: {
activeFlag: 'false',
shiftId: '0',
id: '0',
deleteFlag: 'false'
},
id: '124',
status: 'Unassigned',
assignment: {
pnr: {
locator: 'ABCDEF',
connectTime: '0',
id: '0'
},
id: '123',
alerts: 'Delay',
customers: [
{
lastName: 'ANY',
firstName: 'KLJ'
},
{
lastName: 'CHE',
firstName: 'MAK'
}
]
}
}
}
],
storeId: 'MyJsonStore',
proxy: {
type: 'ajax',
reader: {
type: 'json'
}
},
fields: [
{
name: 'work'
}
]
}
});
If you get the config working like I have then you can gradually add in your models and associations, as-well as your ajax loading, testing all the way, this should help you to discover what the issue is.
Also, you might want to consider using tools like Json Lint when your working with JSON data, the original JSON blob you posted was difficult to read and badly formatted, all of which makes developing more difficult.

Categories