How to load associations conditionaly in sequlize.js? - javascript

Post.findAndCountAll({
include: [{
model: models.like,
where: { userId: req.authSession.user.id }
]}
}).then( collection => {
onSucess(collection);
});
This will load posts if they have an associated like from the user. However what I want is loading all the user's post and loading the associated like if its exist. Can I archive this behaviour somehow with sequlize.js?

You just need to nest the where clause one level above.
Post.findAndCountAll({
where: { userId: req.authSession.user.id },
include: [{model: models.like}]
}).then( collection => {
onSucess(collection);
});
This will return all Posts that have userId === req.authSession.user.id and will include their likes ( if any ).
Edit according to the comment
If you want to have the Likes of the user you can just revert the query
Like.findAndCountAll({
where: { userId: req.authSession.user.id },
include: [ { model: models.post } ]
});

Related

Only return items from db if the include items exists (Prisma)

I am trying to only return items from our DB, if the children within an include exists.
I am using Prisma to query our postgres DB. Previously, using sequelize, you could add a required:true to the include, meaning only items that had this include would be returned. However, I can not seem to do this with Prisma, so its returning many more items that I don't need.
Here is the structure that i have:
where: {
...parameters_.where,
},
include: {
Products: {
where: {
active: true,
ParentId: parameters_.ParentId,
},
}
}
So I only want to return the top level, if Products actually exists. (This will return an array, and currently it returns if the Products array is empty as well as when its not).
As mentioned, with sequelize it was possible to do the following:
include: [
{
model: ModelName,
as: "modelName",
required: true
},
]

Retrive some columns of relations in typeorm

I need to retrieve just some columns of relations in typeorm query.
I have an entity Environment that has an relation with Document, I want select environment with just url of document, how to do this in typeorm findOne/findAndCount methods?
To do that you have to use a querybuilder, here's an example:
return this.createQueryBuilder('environment') // use this if the query used inside of your entity's repository or getRepository(Environment)...
.select(["environment.id","environment.xx","environment.xx","document.url"])
.leftJoin("environment.document", "document")
.where("environment.id = :id ", { id: id })
.getOne();
Sorry I can't add comment to post above. If you by not parsed data mean something like "environment.id" instead of "id"
try this:
return this.createQueryBuilder("environment")
.getRepository(Environment)
.select([
"environment.id AS id",
"environment.xx AS xx",
"document.url AS url",
])
.leftJoin("environment.document", "document")
.where("environment.id = :id ", { id: id })
.getRawOne();
Here is the code that works for me, and it doesn't require using the QueryBuilder. I'm using the EntityManager approach, so assuming you have one of those from an existing DataSource, try this:
const environment = await this.entityManager.findOne(Environment, {
select: {
document: {
url: true,
}
},
relations: {
document: true
},
where: {
id: environmentId
},
});
Even though the Environment attributes are not specified in the select clause, my experience is that they are all returned in the results, along with document.url.
In one of the applications that I'm working on, I have the need to bring back attributes from doubled-nested relationships, and I've gotten that to work in a similar way, shown below.
Assuming an object model where an Episode has many CareTeamMembers, and each CareTeamMember has a User, something like the code below will fetch all episodes (all attributes) along with the first and last name of the associated Users:
const episodes = await this.entityManager.find(Episode, {
select: {
careTeamMembers: {
id: true, // Required for this to work
user: {
id: true,
firstName: true,
lastName: true,
},
}
},
relations: {
careTeamMembers: {
user: true,
}
},
where: {
deleted: false,
},
});
For some reason, I have to include at least one attribute from the CareTeamMembers entity itself (I'm using the id) for this approach to work.

in nested eager loading sequelize query, fetch only some attributes

Here's my query for fetching shows from a database, plus its associated venue and bands.
I really only want to get the names of the bands and venue. (name is the field in both of those tables.) The code below is fetching the whole record, though, and not just the field that I want.
const getAllShows = async (req, res) => {
try {
const shows = await Show.findAll({
include: [
{ model: User, as: 'bands', through: { attributes: ['name'] } },
{ model: Venue, through: { attributes: ['name'] }}
],
});
res.status(200).send(shows);
}
catch(err) {
res.send(400);
}
}
The attributes is misplaced - it doesn't belong under the through (btw, depending on your associations, you may not even need through).
Try changing like this:
{ model: User, as: 'bands', attributes: ['name']},
You might also consider field aliases, like this:
{ model: User, as: 'bands', attributes: [['name', 'band_name']]},
hth

Meteor publish-composite and nested collection

I am trying to build an app that has a many to many relationship in Meteor. There will be jobs, clients and users collections. Clients can have multiple jobs, and most importantly multiple users can work on the same job.
I have the jobs collection set up as follows in my fixtures file:
Jobs.insert({
jobNum: 'Somejob',
clientId: 'XXXXXXXX',
clientName: 'Some Client',
rate: XX,
userNames: [
{userId: user1._id},
{userId: user2._id}
],
active: true
});
I am publishing according to the readme for publish-composite, but I cannot get the users to publish to the client. Here is the publication code:
Meteor.publishComposite('jobsActive', {
find: function() {
// Find all active jobs any client
return Jobs.find({active: true});
},
children: [
{
find: function (job) {
// Return a client associated with the job
return Clients.find({_id: job.clientId});
}
},
{
find: function (job) {
// Return all users associated with the job
// This is where the problem is
return Meteor.users.find({_id: job.userNames.userId});
}
}
]
});
I can't figure out how to correctly find over an array. I tried a number of things and nothing worked. Is this possible? Or do I need to go about this in another way? I've thought about referencing jobs in the users collection, but there will be far more jobs than users, so it seems to make more sense like this.
BTW, I did subscribe to 'jobsActive' as well. The other two collections are coming over to the client side fine; I just can't get the users collection to publish.
Thanks for any help and ideas.
job.userNames.userId doesn't exist in your collection. job.userNames is an array of objects which have the key userId.
Try something like _.map( job.userNames, function( users ){ return users.userId } ).
Your code will be:
Meteor.publishComposite('jobsActive', {
find: function() {
return Jobs.find({active: true});
},
children: [
{
find: function (job) {
return Clients.find({_id: job.clientId});
}
},
{
find: function (job) {
return Meteor.users.find({ _id: { $in: _.map( job.userNames, function( users ) { return users.userId } ) } });
}
}
]
});
I think you don't need publish-composite at all, try this code snippet. It works for me!
Meteor.publish('jobsActive', function () {
return Events.find(
{
$or: [
// { public: { $eq: true } },
{ active: true },
{ userNames: this.userId}
],
},
{
sort: {createdAt: -1}
}
);
});

How to get result with specific fields in StrongLoop?

I am currently using StrongLoop as my API backend server and Mongodb as data storage engine.
Let's say there is a collection called article. It has two fields title, and content. And there are two frontend pages to display a list of articles and view a single article.
Obviously the data list page only need title field and the view page need both. Currently the GET method of StrongLoop API return all fields including content. It cost extra traffic. Is there any way that can just return specific field?
Mongodb support projection in find() method for this. How can I do the same thing by StrongLoop?
Have you taken a look at the filters offered. http://docs.strongloop.com/display/LB/Querying+models
Query for NodeAPI:
server.models.Student.findOne({where: {RFID: id},fields: {id: true,schoolId: true,classId: true}}, function (err, data) {
if (err)
callback(err);
else {
callback();
}
})
Query for RestAPI :
$http.get('http://localhost:3000/api/services?filter[fields][id]=true&filter[fields][make]=true&filter[fields][model]=true')
.then(function (response) {
}, function (error) {
});
You can use fields projections,
Sample Record:
{ name: 'Something', title: 'mr', description: 'some desc', patient: { name: 'Asvf', age: 20, address: { street: 1 }}}
First Level Projection:
model.find({ fields: { name: 1, description: 1, title: 0 } })
and I think Strong loop is not yet supporting for second-level object filter, does anyone know how to filter second-level object properties or is yet to implement?.
Second Level Projection: (Need help here)
Ex: 2
model.find({ fields: { name: 1, 'patient.name': 1, 'patient.age': 1, 'patient.address': 0 } })
// Which results { name } only

Categories