mongodb aggregation query to include a specific field - mongodb-query

I have a mongodb schema which looks like
{
post_id: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "Post"
},
comment_by: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: "User"
},
comment: {
type: String,
required: true
},
parent_comment_id: {
type: mongoose.Schema.Types.ObjectId,
ref: "Comment"
},
is_deleted: {
type: Boolean,
default: false
}
}
I want to group the comments such that
they have common "parent_comment_id" but I also want to include the "comment" field of the
document whose "id" is "parent_comment_id".
This is query I have written
var comments = await Comment.aggregate([
{
"$match": {
post_id: mongoose.Types.ObjectId(post_id)
}
},
{
"$group": {
_id: `$parent_comment_id`,
replies: { "$count": {} }
}
}
])
and the result is
{ _id: new ObjectId("6278e11fa7887263e6e6fada"), replies: 3 },
{ _id: new ObjectId("6278fb9f6a8d30c46eb53a84"), replies: 5 },
{ _id: null, replies: 2 }
Result I want
{ _id: new ObjectId("6278e11fa7887263e6e6fada"), replies: 3 , comment : <comment>},
{ _id: new ObjectId("6278fb9f6a8d30c46eb53a84"), replies: 5 , comment : <comment>},

Welcome heeya joshi!.
You can do something like this:
db.collection.aggregate([
{
$match: {post_id: mongoose.Types.ObjectId(post_id)}
},
{
$addFields: {
parent_comment_id: {$ifNull: ["$parent_comment_id", "$_id"]}
}
},
{
$group: {
_id: "$parent_comment_id",
"comment": {
$push: {
$cond: [
{$eq: ["$parent_comment_id", "$_id"]},
"$comment",
"$$REMOVE"
]
}
},
replies: {"$count": {}}
}
},
{
$project: {
comment: {$arrayElemAt: ["$comment", 0]},
replies: 1
}
}
])
As you can see here.
After your $match, the addFields adds the parent_comment_id to the parents themselves. Then the $group keeps the comment only for the parents.

Related

I need ordering the user's likes with start current user like in prisma

I am using prisma.
I need to get likes of posts with last 3 liked user .
So I want to get these user that starts with current user like .
Becouse I can check is liked this post in frontend part easly.
How can I do this issue with prisma.
Thanks for your help :)
let posts = await prisma.posts.findMany({
where: {
active: true,
},
orderBy: {
id: 'desc'
},
select: {
id: true,
userId: true,
text: true,
files: {
select: {
files: true
}
},
createdAt: true,
active: true,
user: {
select: {
id: true,
fullName: true,
profileImg: {
select: {
url: true
}
}
},
},
_count: {
select: {
likes: true,
comments: true
}
},
likes: {
orderBy: {
id: 'desc'
},
select: {
postId: true,
userId: true,
user: {
select: {
id: true,
fullName: true,
profileImg: {
select: {
url: true
}
}
},
}
},
take: 3
}
},
})

ExpressJs - Mongoose: Delete documents with Many To Many relationship

I've two Models, Post and Tag with Many To Many relationships.
Post Schema:
const postSchema = new Schema(
{
user: {
type: Schema.Types.ObjectId,
ref: 'User',
required: [true, 'A post must belong to a user.'],
},
title: {
type: String,
unique: [true, 'A Post already exists with this title.'],
required: [true, 'A Post must have a title.'],
},
slug: { type: String, unique: true },
body: { type: String, required: [true, 'A Post must have a body.'] },
coverImage: String,
images: Array,
isDraft: { type: Boolean, default: false },
isPublished: { type: Boolean, default: false },
tags: [{ type: Schema.Types.ObjectId, ref: 'Tag' }],
},
{
timestamps: { currentTime: () => Math.floor(Date.now() / 1000) },
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
)
Tag Schema:
const tagSchema = new Schema(
{
title: { type: String, required: true },
slug: { type: String },
posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }],
},
{
timestamps: { currentTime: () => Math.floor(Date.now() / 1000) },
toJSON: { virtuals: true },
toObject: { virtuals: true },
}
)
Now I want to remove all the references of the Posts from the Tag documents when a Post is deleted.
I'm trying to the following remove middleware in the Post model but it is not working. The post get deleted but the reference still there on the Tag documents.
postSchema.pre('remove', function (next) {
var post = this
post
.model('Tag')
.update(
{ posts: { $in: post.tags } },
{ $pull: { posts: post._id } },
{ multi: true },
next
)
})
After trying many times I finally fired out what wrong I was doing. Following the fix I made to make it work:
In Post Controller I was previously doing this:
const post = await Post.findByIdAndDelete(req.params.id)
Which I changed to:
const post = await Post.findById(req.params.id)
await post.remove()
And in Post Model:
postSchema.pre('remove', async function (next) {
await this.model('Tag').updateMany(
{ posts: this._id },
{ $pull: { posts: this._id } },
{ multi: true },
next
)
})

structure of xstate config which has condion included & which can be used in vue-kanban pkg

I'm trying to create xstate Machine which has condition to be check when moving to another state(Using VueJs).
issue is the way tried which is not working with vue-kanban(https://github.com/BrockReece/vue-kanban) pkg
below is my sample state machine config :
stateMachineConfig: {
id: "kanban",
initial: "on-hold",
states: {
"on-hold": {
on: {
IN_PROGRESS:"in-progress",
}
},
"in-progress": {
on: {
RELINQUISH_TASK: "on-hold",
PUSH_TO_QA: "needs-review",
},
},
"needs-review": {
on: {
REQUEST_CHANGE: "in-progress",
PASS_QA: "approved",
},
},
approved: {
type: "final",
},
},
},
this is the UI of kanban(https://ibb.co/6rWxN0F)
after i changing above config by adding condition to "on-hold" state then i can't move to anywhere from "on-hold" state.
below is the new config:
const searchValid = (context) => {
console.log(`context.status `, context);
return true;
};
stateMachineConfig: {
id: "kanban",
initial: "on-hold",
states: {
"on-hold": {
on: {
PICK_UP: [
{
target: "in-progress",
cond: searchValid
}
]
}
},
"in-progress": {
on: {
RELINQUISH_TASK: "on-hold",
PUSH_TO_QA: "needs-review",
},
},
"needs-review": {
on: {
REQUEST_CHANGE: "in-progress",
PASS_QA: "approved",
},
},
approved: {
type: "final",
},
},
},
any help to fix it!
I have tested your machine using the XState visualizer and all works properly, you can check it here

How to track changes in a property stored in Vuex(store) and perform some method based on the value?

I'm trying to change the links based on the variable user_role which is stored in Vuex(store). I'm not able to find an appropriate way to track the change and based on its value I want to perform some method. Any suggestions on how to do it?
------------------------------store.js-------------------------------
export default new Vuex.Store({
state: {
user_role: "User"
},
mutations: {},
actions: {},
modules: {}
});
-----------------------------------component.vue---------------------------
export default {
name: "Navbar",
data() {
return {
links: [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "", route: "" },
{ text: "Resources", route: "/resources" }
],
pers_actions: ["Profile", "LogOut"],
};
},
watch: {
user_role: {
if (user_role === "PM") {
this.links[2] = {
text: "Allocations",
route: "/allocations"
};
} else if (user_role === "PMO") {
this.links[2] = {
text: "Reports",
route: "/reports"
};
} else if (user_role === "User") {
this.links = [
{
text: "Allocations",
route: "/allocations"
}
];
}
}
},
Rather than explicitly mutating your local data in response to some state change, it is better to compute your links within a computed property because it will automatically update whenever some dependent data has changed. It'll "just work".
computed: {
links() {
switch (this.$store.state.user_role) {
case: "PM": return [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "Allocations", route: "/allocations" },
{ text: "Resources", route: "/resources" },
];
case: "PMO": return [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "Reports", route: "/reports" },
{ text: "Resources", route: "/resources" },
];
// For any other role
default: return [
{ text: "Allocations", route: "/allocations" },
];
}
}
}

Apollo-Client | No result from query when using certain fields

I'm trying to use apollo-client in my react-native app but for some reason I can only get results from queries when I use certain fields.
Here's my first query :
`query RootQueryType($page: Int!) {
events(page: $page) {
title
}
}`
Working perfectly in RN and GraphiQL but as soon as I add or use an other field than title I don't get any result from the query in RN. It's working perfectly in GraphiQL and there's no error at all.
For example :
`query RootQueryType($page: Int!) {
events(page: $page) {
description
}
}`
Here's my event type :
const EventType = new GraphQLObjectType({
name: 'EventType',
fields: () => ({
id: { type: GraphQLID },
title: { type: GraphQLString },
category: { type: GraphQLString },
description: { type: GraphQLString },
terminated: { type: GraphQLBoolean },
coverUrl: { type: GraphQLString },
startDate: { type: GraphQLString },
endDate: { type: GraphQLString },
price: { type: GraphQLFloat },
website: { type: GraphQLString },
ticketsUrl: { type: GraphQLString },
geometry: { type: GraphQLString },
participantsCount: { type: GraphQLInt },
participants: {
type: new GraphQLList(UserType),
resolve(parentValue) {
return Event.findParticipants(parentValue.id);
}
}
})
});