Prisma: use count inside a mutation resolver - node.js

I have a mutation createPet and want it to throw an error if the user already has 5 pets created.
I was thinking that something like this will work but it doesn't:
const petsCount = await db.pets({
where: { owner: user.id },
}).count();
I also didn't find anything in the docs

To retrieve a count, you can use Aggregations:
const petsCount = await prisma
.petsConnection({where: {owner: user.id}})
.aggregate()
.count()
Source: documentation

Related

Mongoose findOneAndUpdate() using current data

I am try to track the number of downloads per click on a website.
server.js
router.post("/download", async (req, res) => {
let id = req.body.id;
id = parseInt(id);
let doc = await db.findOneAndUpdate({_id: id}, {downloads: 100});
});
Note: This works
But I'm trying to increase the number by 1 each time.
For example: Let's say the current number of downloads is 5, how do I do it that if there's a post request. The number of downloads increases by 1.
const { body: { id } } = req;
const intCasetedId = parseInt(id);
const retrievedDocument = await db.findOneAndUpdate({ id }, { $inc: { downloads: 1 } });
A couple things are happening here.
First I get the id value from the the req argument using a destructuring assignment.
I use only const to ensure I do not mutate variable values.
I also use the object property value shorthand notation to skip '_id' key in the search query argument. Quoting mongoose documentation:
Issues a mongodb findAndModify update command by a document's _id field. findByIdAndUpdate(id, ...) is equivalent to findOneAndUpdate({ _id: id }, ...).
Then I am using '$inc' operator to increment the downloads field by 1.
I would also highly recommend for you to research eslint

Firestore promise wait for product details before returning products

I know similar questions like this have been asked 1000 times but for the life of me I am struggling with something I feel is quite simple.
We have 2 tables, one called order_lines the other called order_lines_meta, I need to first query order_lines and for each line get the order_lines_meta and return that
I have tried a lot of variations, here is where I am at and stuck, I need it to wait for the order_lines_meta to come back because otherwise I get blank metaData as the data comes after nodejs has already outputted the order_lines
At the end an object that contains order info, line items of objects and within line items a meta data object
Appreciate the help, I just can't seem to wrap my brain on this one , and I am certainly open to other ways of doing this as well
Using nodejs, express, typescript, firestore
const orderNumber = req.query.orderNumber as string;
const customerName = req.query.customerName as string;
const orderDate = req.query.orderDate as string;
const pickListObj = {
orderNumber: orderNumber,
customerName: customerName,
orderDate: orderDate,
line_items: <any>[],
};
db.collection('order_lines').where('number', '==', orderNumber).get().then((snap) => {
const promises = <any>[];
snap.forEach(async (order: any) => {
// get meta data
const metaDataObj = <any>[];
const productName = order.data().name;
const productQty = order.data().quantity;
promises.push(db.collection('worder_line_meta').where('lineId', '==', order.data().lineId).get().then((doc: any) => {
if (doc.display_value != '') {
const meta = [{display_key: doc.data().display_key, display_value: doc.data().display_value}];
metaDataObj.push(meta);
}
}));
});
return Promise.all(promises);
}).then(() => {
pickListObj.line_items.push({name: productName, quantity: productQty, meta_data: metaDataObj});
});
Move the push statement from the last .then inside the previous .then:
promises.push(db.collection('worder_line_meta')...then((doc: any) => {
if (doc.display_value != '') {
...
}
pickListObj.line_items.push({name: productName,
quantity: productQty,
meta_data: metaDataObj});
}));
In the last .then, you will then find the complete pickListObj.
However, I wonder whether it might be simpler and faster to join the two database collections right on the database and retrieve everything with one db.collection operation.

Is there a way I can use Group By and Count with Type Orm Repository

I am new here recently joined and New in Type ORM My code that I am trying
FIRST QUERY: I would like to use this approach but not sure how I can group by with count on the column and then order by desc on that column
const result = await this.jobViewsRepository.find({
relations: ["jobs"],
loadEagerRelations: true,
order: { id: "DESC" },
skip: offset,
take: limit,
}
);
I am trying if I can use this in my above query
SECOND QUERY: IT'S WORKING FOR ME PERFECTLY THE RESULT I AM LOOKING
const res = await this.jobViewsRepository.createQueryBuilder('jobViews')
.addSelect("COUNT(jobViews.user_id) AS jobViews_total_count" )
.leftJoinAndSelect(Jobs, "jobs", "jobs.id = jobViews.job_id")
.where("jobs.user_id != :id", { id: user_id })
.groupBy("jobViews.job_id")**
.orderBy('jobViews_total_count', 'DESC')**
.limit(limit)
.offset(offset)
.getRawMany();
Please if any can help me out in this will be really appreciated
Thanks
At least in the current version there is no way to do this feature (neither in the documentation nor in the web)
I believe you can use .query to write your own query
Now is the only one way is to use queryBuilder And .groupBy("user.id") with .addGroupBy("user.id")
https://orkhan.gitbook.io/typeorm/docs/select-query-builder#adding-group-by-expression
Or write raw query:
import { getManager } from 'typeorm';
const entityManager = getManager();
const someQuery = await entityManager.query(`
SELECT
fw."X",
fw."Y",
ew.*
FROM "table1" as fw
JOIN "table2" as ew
ON fw."X" = $1 AND ew.id = fw."Y";
`, [param1]);
you use findAndCount to count the result size
result = await this.jobViewsRepository.findAndCount({ ... })
the result = [data,count]

How do I use transactions or batches to read the value of an update, then perform more updates using that value?

What is the best approach to do a batch update or transaction, that reads a value of the first update, then uses this value to make further updates?
Here is an example:
//create person
const id = await db
.collection("person")
.add({ ...person })
.then(ref => ref.id)
//then do a series of updates
let batch = db.batch()
const private_doc = db
.collection("person")
.doc(id)
.collection("private")
.doc("data")
batch.set(private_doc, {
last_modified,
version: 1,
versions: []
})
const some_index = db.collection("data").doc("some_index")
batch.update(some_index, {
[id]: { first_name: person.first_name, last_name: person.last_name, last_modified }
})
const another_helpful_doc = db.collection("some_other_collection").doc("another_helpful_doc")
batch.update(another_helpful_doc, {
[id]: { first_name: person.first_name, last_name: person.last_name, image: person.image }
})
return batch.commit().then(() => {
person.id = id
return person
})
You can see here if there is an error any of the batch updates, the person doc will still be created - which is bad. I could add in a catch to delete the person doc if anything fails, however interested to see if this is possible with transactions or batches.
You can call the doc() method, without specifying any path, in order to create a DocumentReference with an auto-generated ID and, then, use the reference later. Note that the document corresponding to the DocumentReference is NOT created.
So, the following would do the trick, since all the writes/updates are included in the batched write:
const new_person_ref = db.collection("person").doc();
const id = new_person_ref.id;
let batch = db.batch()
batch.set(new_person_ref, { ...person })
const private_doc_ref = db // <- note the addition of ref to the variable name, it could help avoiding errors, as this is not a DocumentSnapshot but a DocumentReference.
.collection("person")
.doc(id)
.collection("private")
.doc("data")
batch.set(private_doc_ref, {
last_modified,
version: 1,
versions: []
})
//....

How to clone/copy instance item/row in sequelize

I tried to find a way to copy/clone instances in Sequelize but without success. Is there any way to do it with a built-in function or without? What I want is to simply copy rows in the database and the new item should have only a different id.
There is no such direct function for that , What you can do is :
Fetch the object that you want to clone/copy
Remove Primary Key from it
Make a new entry from it
model.findOne({ //<---------- 1
where : { id : 1 } ,
raw : true })
.then(data => {
delete data.id; //<---------- 2
model.create(data); //<---------- 3
})
As said, there is no such direct function for that (thanks Vivek)
If you find useful, place the following code on your model class:
async clone() {
let cData = await THISISMYMODEL.findOne({
where: { id: this.id},
raw: true,
});
delete cData.id;
return await THISISMYMODEL.create(data);
}
Take into account that "THISISMYMODEL" should be the model class defined and "id" the primary key attribute used.
Also take into account the use of Foreign Keys (relations with other models), it will use the same keys. Otherwise you should clone those instances too.
You may need to update the name though or some other field to identify it as a copy,
const data = await model.findOne({ where: {id: 1}, raw: true, attributes: { exclude: ['id'] } });
data.name = data.name + '(copy)';
const newRecord = await model.create(data);
Write a Model.create(data) function inside Model.js and call this function from inside of a loop, as many times you need it will create the copy of the same data.

Resources