How to use where in in Prisma? - prisma

I have made a query below that search user using two columns. But it seems not working properly, I assume it is querying the where clause in each column instead of both columns.
Is there a way we could where ~ in for two or more columns?
const users = [
{
user_id: 1,
school_id: 11,
..
},
{
user_id: 2,
school_id: 22
},
..
]
await prisma.user.findMany({
where: {
AND: {
user_id: {
in: users.map(user => user.user_id)
},
school_id: {
in: users.map(user => user.school_id)
}
}
}
})
The problem it does not search for both user_id and school_id. Instead it search either of the two column. I will ask assistance of you guys, or do you have better approach with the same result. thanks.

I don't think the AND option works if you send an object. It typically takes an array of objects (https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#examples-46).
The simpler way to do the query is to leave out the AND entirely:
await prisma.user.findMany({
where: {
user_id: {
in: users.map(user => user.user_id)
},
school_id: {
in: users.map(user => user.school_id)
}
}
})
This is essentially an 'implicit' AND.

Related

use where query depends on query on prisma

const fictions = await client.fiction.findMany({
where: {
AND: [
{ genre: genres as string },
{ nationality: nationalities as string },
{
keywords: {
some: {
keyword: {
name: keywords?.toString().split(",").join(" | "),
},
},
},
},
],
},
include: { ~~~
},
orderBy: {
userFictionStat: {
total: "asc",
},
},
});
Hi, I'm new to prisma so stuck in createing api pages.
I want to filter my 'fictions' with multiple criteria
('genre' or 'nationality' or 'keywords').
The problem is that when 'genre' or 'nationality' or 'keywords' are 'undefined'(button unclicked), the result becomes 0.(because of the 'AND').
I can't find out how can I filter my fictions with given criteria(with clicked buttons, even if some buttons are unclicked).
Also, I'd like to know how can I sort my fictions using my queries.
(lik if i get query {sorting : totalpoint} I can sory by totalPoint, and if i get {sorting : title} then I can sort by title name.
If anyone could help, I would be very thank you.
If genres can be undefined or false-y (including '' or "") then you can do typeof genres === "string" ? genres : undefined as part of your filter. Same for nationalities. That way you know you're passing a string which has meaningful content OR you are ignoring the filter.

Prisma splice Item from Array

I have been pushing updates to an array and was wondering if there is a built-in method to remove an entry from the array as well. Basically reversing the push command. I suspect that I have to query all documents and remove the item myself. But maybe there is some functionality I was unable to find inside the documentation.
Push:
const addTag = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
push: 'computing',
},
},
})
Remove Expectation:
const removeTag = await prisma.post.update({
where: {
id: 9,
},
data: {
tags: {
splice: 'computing',
},
},
})
As of writing, there's no method to splice/remove items from a scalar list using Prisma. You would have to fetch the scalar list from your database, modify it manually in your application code and overwrite the record in your database with an update operation.
There is a feature request for this, please feel free to follow/comment with your use-case to help us track demand for this feature.
const { dogs } = await prisma.user.findOne({
where: {
id: userId
},
select: {
dogs: true
},
});
await prisma.user.update({
where: {
id: userId
},
data: {
dogs: {
set: dogs.filter((id) => id !== 'corgi'),
},
},
});

Mongoose query using if else possible?

I have this Schema:
const guestSchema = new Schema({
id: String,
cart: [
{
product: {
type: mongoose.Schema.ObjectId,
ref: "products"
},
quantity: Number
}
]
});
I have this query:
Guest.findOneAndUpdate(
{ id: req.sessionID },
{
$cond: [
{ "cart.product": { $ne: req.body.itemID } },
{ $push: { "cart": { product: req.body.itemID, quantity: 1 } } },
{ $inc: { "cart.quantity": 1 } }
]
},
{ upsert: true, new: true }
).exec(function(err, docs) {
err ? console.log(err) : res.send(docs);
});
Basically, what I'm trying to do is update based on a condition. I tried using $cond, but found out that operator isn't used for querys like I'm doing.
Based on this:
{ $cond: [ <boolean-expression>, <true-case>, <false-case> ] }
I want something similar to the functionality of this operator for my query.
Let's break down my condition:
For my boolean expression: I want to check if req.body.itemID is $ne to any of the values in my cart
If true then: $push the itemID and quantity into the cart
Else (then item already exists): $inc the quantity by 1
Question: How would achieve this result? Do I need to make two seperate querys? I'm trying to avoid doing that if possible
I went through all their Update Field Operators, and there's probably no way to do this in the way I want.
I wonder why there is no $cond for update operators. Nonetheless, I have the solution to what I wanted the functionality accomplish. Just not in the elegant fashion that I would like it.
Guest.findOneAndUpdate(
{ id: req.sessionID },
{ id: req.sessionID }, //This is here in case need to upsert new guest
{ upsert: true, new: true }
).exec(function(err, docs) {
if (err) {
console.log(err);
} else {
//Find the index of the item in my cart
//Returns (-1) if not found
const item = doc.cart.findIndex(
item => item.product == req.body.itemID
);
if (item !== -1) {
//Item found, so increment quantity by 1
doc.cart[item].quantity += 1;
} else {
//Item not found, so push into cart array
doc.cart.push({ product: req.body.itemID, quantity: 1 });
}
doc.save();
}
});
This type of logic does not belong within the database query. It should happen in the application layer. MongoDB is also very fast at retrieving and updating single records with an index so that should not be a concern.
Please try doing something like this:
try {
const guest = await Guest.findOne().where({
id: req.sessionID
}).exec();
// your cond logic, and update the object
await guest.save();
res.status(200).json(guest);
} catch (error) {
handleError(res, error.message);
}

Distinct Query with Cloudant Connector using Loopback in API Connect/StrongLoop

I am trying to get distinct values for a query using Loopback with a Cloudant Connector, but I haven't found anything about this in the documentation.
e.g. I need a query to turn this:
[
{
rating: "★★★★★"
},
{
rating: "★★★★★"
},
{
rating: "★★★★★"
},
{
rating: "★★★★★"
},
{
rating: "★★★☆☆"
},
{
rating: "★★★☆☆"
}
]
into this:
[
{
rating: "★★★★★"
},
{
rating: "★★★☆☆"
}
]
I'm using the REST API to query my Products model (above is a filtered view of just the rating field). If there is some sort of filter that I can use without modifying the server that I somehow just missed in the documentation, that would be the best choice.
Is there any way I can add a distinct field like:
/Products?filter[fields][rating]=true?distinct=true
or how can I go about solving this?
Also, I've seen another answer talking about adding a remote method to solve this (something like this for mySQL):
Locations.regions = function (cb) {
var ds = Locations.app.datasources.myDS;
var sql = "SELECT DISTINCT region FROM Locations ORDER BY region"; // here you write your sql query.
ds.connector.execute(sql, [], function (err, regions) {
if (err) {
cb(err, null);
} else {
cb(null, regions);
}
});
};
Locations.remoteMethod(
'regions', {
http: {
path: '/regions',
verb: 'get'
},
returns: {
root: true,
type: 'object'
}
}
);
If this would work, how would I implement it with the Cloudant NoSQL DB connector?
Thanks!
If your documents looked like this:
{
"name": "Star Wars",
"year": 1978,
"rating": "*****"
}
You can create a MapReduce view, which emits doc.rating as the key and uses the build-in _count reducer:
function(doc) {
emit(doc.rating,null);
}
When you query this view with group=true, distinct values of rating will be presented with counts of their occurrence in the data set.

How to filter objects with subquery?

Usking shiki/kaiseki to interact with the Parse REST api. I'm trying to get all As that do not have a related B for a user.
I know I can get Bs for a user:
parseClient.getObjects('B', {
where: {
user: {
__type: "Pointer",
objectId: "id here",
className: "_User"
}
},
keys: 'a'
}, callback)
And then pluck object ids to get the bad A ids.
aIds = [ Bs ].map(function (b) {
return b.a.objectId
})
And then query for As negative matching the id.
parseClient.getObjects('A', {
where: {
objectId: { $nin: aIds }
}
}, callback)
But a user can have more B's than the query limit of 200. How can I rewrite it to use a subquery?
$dontSelect
Nested key param doesn't work, which makes something like this fall flat.
parseClient.getObjects('A', {
where: {
objectId: {
$dontSelect: {
query: {
className: 'B',
where: { user query },
},
key: 'a.objectId
}
}
}
}, callback)
// { code: 105, error: 'invalid field name: ' }
$notInQuery
There doesn't seem to be a way to put $notInQuery in the root of the where or to reference the current object.
parseClient.getObjects('A', {
where: {
$notInQuery: {
className: 'B',
where: { user query },
key: 'a'
}
}
}, callback)
// { code: 102, error: 'Invalid key $notInQuery for find' }
Help!
It is a limitation of the Parse model, and the only way I have found around it is to adjust your schema accordingly.
One way you could do it is with a relation on A that contains all related User pointers and then do a $ne against the relation field:
where: {
'relationColumn' : {
'$ne': {
'__type': 'Pointer',
'className': '_User',
'objectId': 'user b id here'
}
}
}