Prisma Connection WhereInput for Array of enum values? - javascript

Doing this 👇
query {
postsConnection(where: {
status: PUBLISHED
}) {
aggregate {
count
}
edges {
cursor
node {
id
slug
}
}
}
}
gives me postsConnection of published posts.
The Post model has an array of Category enum in field categories. This is the Post in datamodel 👇
enum Category {
TECH
FIN
DIGIMARK
CODING
TUTORIAL
HOWTO
WRITING
INSPIRE
SCIENCE
POLITICS
LIFESTYLE
}
type Post {
id: ID!
title: String!
editorSerializedOutput: Json!
editorCurrentContent: Json!
editorHtml: String!
updatedAt: DateTime!
createdAt: DateTime!
author: User
authorId: String!
categories: [Category!]!
thumbnail: Json!
status: PostStatus!
slug: String!
}
My question is, what Prisma Query do I need to write to get PostConnection of posts in a specific category?

Prisma doesn't yet allow filtering with Enum (see issue on github)
You can however make a to-many relation with a new Type Category that you can create

Related

Populate and Aggregate MongoDB documents

I am currently working with mongoose ODM and MongoDB. Currently, I have faced a tiny issue that I can't seem to get going. So I have a User collection like so:
const userSchema = new Schema({
name: String,
posts: [{type: Schema.Types.ObjectId, ref: 'Post'}],
createdAt: Date,
updatedAt: Date
})
and a Post collection like so:
const postSchema = new Schema({
text: String,
user: {type: Schema.Types.ObjectId, ref: 'User'},
createdAt: Date,
updatedAt: Date
})
The user collection has a posts field embedded in it that is an array of the user posts. A typical example of what it looks like is given below:
{
_id: 56we389iopks,
name: John,
posts: ['6748ufhsgshsklop...', '5e43tiodo...']
}
A user has an array of posts, I find the user by their respective ID and populate the posts array.
AIM
I want to be able to fetch a user by their ID and get all posts, which are sorted with the newest and oldest post. I know mongoose has an aggregate method, but I don't know how to go about this. Thank you, any help will be appreciated.
Example of expected output document:
const user = {
_id: 5e34647489930hhff494,
name: John,
posts: [
{
text: 'aloha',
createdAt: 2021-08-30 // newest post
updatedAt: 2021-08-30
},
{
text: 'heyyy',
createdAt: 2021-02-14 // oldest post
updatedAt: 2021-02-14
},
]
}
You have the #Populate from Mongoose that can help you out.
Let's try the following
Let's retrieve posts by User
const postsByUser = await User
.find({ _id: '...' })
.populate('posts');
console.log('postsByUser', postsByUser);
Once we're able to retrieve the posts, let's improve it ordering them by the createdAt
const postsByUserOrdered = await User
.find({ _id: '...' })
.populate({
path: 'posts',
options: { sort: { 'createdAt': -1 } }
})
.exec();
console.log('postsByUserOrdered', postsByUserOrdered);

Schema design for chat app with group chat. I can't query chat room in chronological order

I'm working on a chat app that allows group app. In order for me to achieve group chat feature, I added a table called ChatRoomUser that connects ChatRoom and Message tables. I got everything working but can't figure out to query Chat Room in a chronological order.
query getUser(id: "USER_ID"){
chatRoomUser(sortDirection: DESC) { // Can't query this in chronological order...
items {
id
chatRoom{
id
receiverHasRead
createdBy
}
}
}
}
I was going to update updatedAt under ChatRoomUser when there's a new message in a chat room but that won't be efficient when there's many users in a room. Because I will have to update 100 rows if there's 100 users in a chat room.
What will be the best way to solve this issue?
type User
#model
#auth(rules: [
{ allow: private }
]
) {
id: String!
chatRoomUser: [ChatRoomUser] #connection(name: "UserChatRoomUser", sortField: "updatedAt") # this does not seem like a good way to query
}
type ChatRoomUser
#model
#key(name: "gsi-doesChatRoomExist", fields: ["chatRoomUserUserId", "members"], queryField: "doesChatRoomExist")
#auth(rules: [
{ allow: private }
]
) {
id: ID!
chatRoomUserUserId: String!
chatRoomUserChatRoomId: String!
members: String!
user: User #connection(name: "UserChatRoomUser")
chatRoom: ChatRoom #connection(name: "ChatRoomUserChatRoom")
createdAt: AWSDateTime
updatedAt: AWSDateTime # I was going to use this as sortField
}
type ChatRoom
#model
#auth(rules: [
{ allow: private }
]
) {
id: ID!
createdBy: String!
receiverHasRead: Boolean!
chatRoomUsers: [ChatRoomUser] #connection(name: "ChatRoomUserChatRoom")
messages: [Message] #connection(name: "chatByChatRoom", sortField: "createdAt")
createdAt: AWSDateTime
updatedAt: AWSDateTime
}
type Message
#model
#auth(rules: [
{ allow: private }
]
) {
id: ID!
content: String!
messageChatRoomId: String!
messageUserId: String!
user: User #connection(name: "UserMassages")
chatRoom: ChatRoom #connection(name: "chatByChatRoom")
createdAt: AWSDateTime!
updatedAt: AWSDateTime
}
I have a feeling that I need to change schema design to make this work but can't think of any solution that can work.
You'll want to implement a key that lets you query your Chatroom for Messages by createdAt. Check out this page on defining keys for more information.

GraphQL Type relationship / Mongoose Schema / populate()

Having an issue with returning territories related to their Company when running query for retrieving all Companies. When a company is created, a territory is not set. Territories are created separately.
The connections/relations are "territories" within Company and "parentCompany" within Territory. When running getAllTerritories the "parentCompany" is populated correctly (I believe this is due to the fact that you choose the parentCompany upon creation of Territory.
So I guess my question is, What is the best way to populate the territories array on Company when running the getAllCompanies query?
Types:
type Company {
_id: ID
state: String!
name: String
territories: [Territory]
createdAt: String
updatedAt: String
createdBy: User!
}
type Territory {
_id: ID
name: String
parentCompany: Company!
issues: [Issue]
prodAdmins: [ProdAdmin]
masterAgents: [MasterAgent]
createdAt: String
updatedAt: String
createdBy: User!
}
Query:getAllCompanies: [Company]
getAllCompanies: async (_, args, { Company, Territory }) => {
const companies = await Company.find({})
.sort({ createdAt: 'desc' })
.populate({
path: 'territories',
model: 'Territory',
})
.populate({
path: 'createdBy',
model: 'User',
});
return companies;
},
On Company schema:
territories: {
type: [mongoose.Schema.Types.ObjectId],
ref: 'Territory',
},

Mongoose - Need two schemas for full and min versions of a model for a document-collection

edited after #enRaiser's answer.
I have a sandbox mongoDB database with a single collection called "hotels", the document-schema of which looks like this:
var roomSchema = new mongoose.Schema({
type: String,
number: Number,
description: String,
photos: [ String ],
price: Number
});
var hotelSchema = new mongoose.Schema({
name: String,
stars: Number,
description: String,
photos: [ String ],
currency: String,
location: {
address: String,
coordinates: [ Number ] /* enforce later validation to have max of two numbers in the array */
},
rooms: [roomSchema],
reviews: [{
name: String,
id: String,
review: String,
rating: Number
}],
services: [ String ]
});
Now, I'd like to have two versions of schema for Hotel, one for a 'deep' data model and the other for a min model.
var hotelMinSchema = new mongoose.Schema({
name: String,
stars: Number,
location: {
address: String,
coordinates: [ Number ]
},
currency: String
})
module.exports = {
full: mongoose.model('hotel', hotelSchema),
min: mongoose.model('hotel', hotelMinSchema)
}
Aparently I'm not supposed to have two models for a collection.. not so sure. I get this error thrown.
OverwriteModelError: Cannot overwrite hotel model once compiled.
I think there should be a work-around for this. Any help or suggestion would be appreciated.
This is totally wrong way of developing any Database. even in MYSQL, I would not have think of this way of designing DB.
Firstly there are duplicate data. You alwayse have to take care of syncing them.
and 2nd, even in your full model there is duplication of comment. the comment info is present in both User ( i.e the commenter and the blogger)
Irrespective of the DB. when ever you think of solution you have to identify the real entities. here in your use case there are only two entity User and comment. So just make two model. not more.(in case of MYSQL, I would say just make two tables User table and comment table.)
Then set up a relation between them. for that in mongoose learn the how to make relation and how to populate that data based on relation. its just like setting up foreign key in MYSQL.
Sorry, I just found this out.
var hotelListPromise = Hotel.find({})
.select('name stars location currency')
.exec((err, hotelData) => {
// my callback stuff here
});

mongodb aggregate with find features

I have a model similar to this one:
{
email: String,
name: String,
role: String,
location: {
country: String,
city: String
},
contacts: {
email: String,
phone: String
}
}
I need to show in my view the entire users information but I wish to include also how many users from a country there are.
Using aggregate I don't know how to get the full user over the groups I create.
So at the moment what I'm doing is this:
User.find({}, function(err, users) {
User.aggregate([
{ $group: { _id: { country: '$location.country' }, count: { $sum: 1 }}}
], function(err, results) {
res.render('home', {
users: users,
countries: results
});
});
});
As you can see I'm using Find and then aggregate to get both the information I need... but I'm pretty sure there is a way to get it using only aggregate but I can not find how to do that...
If you need to accumulate the entire user information for each group, then you need to use the $push operator for accumulation and the $$ROOT system variable to access the entire user info.
User.aggregate([
{$group:{"_id":{"country":"$location.country"},
"users":{$push:"$$ROOT"},
"count":{$sum:1}}}
],callback)
In case you would want to accumulate only specific fields of the user information document, you could just push the required fields like:
User.aggregate([
{$group:{"_id":{"country":"$location.country"},
"users":{$push:{"email":"$email","name":"$name"}},
"count":{$sum:1}}}
],callback)

Categories

Resources