Prisma findMany() - Ordering by count orders 0 count as positive infinity - prisma

I am trying to findMany() users and orderBy their post count. I found exactly how to do it in the docs and it works except it counts users with 0 posts as +infinity. orderBy: {posts: {count: asc}}
For example, the ordering works in ascending starting with users with 1 post up until the users with a lot of posts, but the last users have 0 posts. Vice versa when descending.
I am using postgres as the provider, I really don’t know how to even google for this problem, and title this question. Please help.
model User {
id Int #id #default(autoincrement())
posts Post[]
}
model Post {
id Int #id #default(autoincrement())
user User #relation(fields: [userID], references: [id])
userID Int
}
await prisma.user.findMany({
orderBy: {
posts: {
count: 'desc',
},
},
});
Output of a small test in descending order. You can see the post count is ordered 0 2 1 (in ascending order its output order is 1 2 0):
[
{ id: 3, _count: { posts: 0 } },
{ id: 1, _count: { posts: 2 } },
{ id: 2, _count: { posts: 1 } }
]

Related

Return id based on existence of multiple value in mongodb

I want to return id based on certain condition like if a user value doesnot exist and both phone and email field matches with search condition with no available userId then i want to get the id of that specific row.If the userid exist it will not return anything.The idea of the query something like this:
db.records.find( { userId: { $exists: false } } )
db.records.find( { phone: "A", email:"B" }, { id: 1} )
how can i merge this query into one and return the only id in mongodb
You can add the queries with commas:
db.records.find( { userId: { $exists: false },phone: "A", email:"B" }, { id: 1} )
Here's an example:
https://mongoplayground.net/p/V_HL7WQqoiO

Mongoose- How to use "where" clause after populate and filtering

I have two Models - product and Category
CategoryId is inside each product Object (Which is referring to _id in Category).
Category Looks like this:
{
"_id": ObjectId("5f3564489dc78d423f75af3d"),
"category": "OVEN",
"__v": 0
}
Product Looks like this
{
"_id": ObjectId("5f36dd21ee0c6c27c04903cc"),
"categoryId": ObjectId("5f358007159810587d26ee5e"),
"__v": 0
}
I want products & I want to do these things in order before getting them:
1. populate categoryId.
2. filter out only required categoryId.
3. Performing limit, skip.
How can I do this?
THIS IS HOW I AM DOING IT CURRENTLY
Product.find({})
.populate({
path: "categoryId",
options: {
limit: limitProductsOnPage,
sort: { rank: 1 },
skip: (page - 1) * limitProductsOnPage
},
})
.exec(function(err, products) {
if (err) {
console.log("Error Occured", err);
}
let filteredProducts;//to Store Filtered Products
filteredProducts = products.filter(product=> { (#POINT-1)
if(product.categoryId._id.toString() == category_id){
return product;
}
});
}
The main problem here is that I am filtering(#POINT-1) after limit and skip! Whereas, filtering must be done before.
I think you can do all that in one query, filtering out the specific category id by by using $ne. Doing something like:
Product.find({categoryId: {$ne: category_id})
.sort({ rank: 1 })
.limit(limitProductsOnPage)
.skip((page - 1)* limitProductsOnPage)
.populate("categoryId")
This should have the required behaviour that you want although it will not be doing it in the exact order that you want.

$addToSet in nested array

I need to perform a $addToSet on an nested array, here an example:
{
_id: 123,
posts:[
{
_id: 234,
userid: 123 //its same id like the documents id,
likesUser: []
}
]
}
My API requires 2 parameters:
The ID of the document, and the Post ID in witch post i want to add.
The ID of the user that liked that post.
If a user likes an Post his User ID should be stored in likesUser.
Lets say a user likes a post. The document have the id 123, first i want to search the document with that ID. After that i want to search the post with the id 234. Now i want to store the ID of the users that liked the post in likesUser, in this case the user have the ID 5d345
{
_id: 123,
posts:[
{
_id: 234,
userid: 123 //its same id like the documents id,
likesUser: ["5d345"]
}
]
}
How do i archieve it? I have tried it with $elemMatch but it doesnt work it throws me error over error.
I have found out the result:
let result = await Post.findOneAndUpdate(
{
_id: mongoose.Types.ObjectId(userId),
"posts._id": mongoose.Types.ObjectId(postId)
},
{
$addToSet: {
"posts.$.likesUser": USER
}
}
);

Graphcool (Graphql): how to make exact filter in array of Id

I have chat model
type Chat #model {
id: ID! #isUnique
name: String
messages: [Message!]! #relation(name: "ChatMessages")
users: [User!]! #relation(name: "ChatUser")
createdAt: DateTime!
}
And I've created a chat with two people ["123", "234"] and all was ok. But when I want to create a new group chat with three people where two of them already have a chat with themselves ["123", "234", "345"]
I make a query for check is this chat exist with three people
query {
allChats(filter:{
users_every: {
id_in: ["123", "234", "345"]
}
}
){
id
users{
id
}
}
}
and I got response that this chat already exist, but here I have just two users not all of them
{
"data": {
"allChats": [
{
"id": "cjgxuub2351uj0187qeil548m",
"users": [
{
"id": "123"
},
{
"id": "234"
}
]
}
]
}
}
The every suffix in users_every makes sure it matches all chats that have only users with ids from the id_in array. That's why you're getting chats with fewer users, because subsets match.
The solution:
query {
allChats(
filter: {
AND: [
{ users_some: { id: "123" } },
{ users_some: { id: "234" } },
{ users_some: { id: "345" } },
{ users_every: { id_not_in: ["678", "910", ...] } }
]
}
) {
id
users {
id
}
}
}
The users_some filters make sure to select chats that have at least all those 3 users attached. The users_every - id_not_in is needed to exclude the chats with those three plus any other users.
In all honesty this seems a bit convoluted to me, and probably kinda unfeasible for an app with a large number of users. I'd love for graph.cool to implement some easier solution in the api.
As an alternative, you could just omit the users_every filter, and then, in your client app, pick from the results only the chat that has exactly 3 users.

MongoDB Indexing many categories in each product, data modeling

Moving from a MySQL database to MongoDB, I have to replicate this feature in a product catalog:
Each product has multiple categories
Each category has a name, id and position of the product in each category
Performance when querying for products by category, sorting by category position or other fields such as price and tags
This is an example of a model I came up with
{
...
categories: [
{
name: 'Clothing',
category_id: 1,
position: 0
},
{
name: 'Bottoms',
category_id: 2,
position: 2
},
{
name: 'Jeans',
category_id: 5,
position: 0
}
]
}
Should I separate the name, category_id and position into different top level fields for indexing?
With your document example provided seems it's impossible to perform search by category with efficient indexing by this category position
Surely, you can index "position", "name" and run query
db.coll.find({"categories.name": "Jeans"}).sort({"categories.position": -1})
But it wouldn't be proper sorting by desired category.
I'd suggest having document part:
{
...
"categories": ["Clothing", "Bottoms", "Jeans"],
"positions": {
"Clothing": 0,
"Bottoms": 2,
"Jeans": 0
}
}
Then you will be able to run query
db.coll.find({categories: "Jeans"}).sort({"positions.Jeans": -1})