I have message document with groupId and createdTS fields.
and for query i have array of objects with groupId and lastVisit.
I want to query all messages per groupId after lastVisit
I tried with $in with groupIds but it is not filtering createdTS with lastVisit
member schema
const GroupMemberSchema = new mongoose.Schema({
userId: { type: String, required: true },
groupId: { type: String, required: true },
addTS: { type: Date, default: Date.now },
lastVisit: { type: Date, default: Date.now }
});
Message Schema
const GroupMessageSchema = new mongoose.Schema({
id: { type: String, required: true },
groupId: { type: String, required: true },
content: { type: String, required: true },
createdTS: { type: Date, default: Date.now },
});
for query
GroupMessage.find({groupId: {$in: groupIds}})
If I understood the question correct then you need to fetch records that match each groupId and at the same time are greater than appropriate lastVisit. If to translate it to MongoDB query it would be something like this:
{
"$or": [
{
"$and": [
{ "groupId": _groupId[i] },
{ "createdTS": { "$gt": _lastVisit[i] } }
]
},
...
]
}
Where _groupId[i] and _lastVisit[i] are array elements for list of groups and lastVisit timestamps.
Related
I'm new at this, I need to get all the persons from the db that matches the day of the week of the attribute createdAt (a Date) and a day of the week obtained through a parameter in the request. My data model is:
const personSchema = new mongoose.Schema({
firstName: {
required: true,
type: String
},
lastName: {
required: true,
type: String
},
age: {
required: true,
type: Number
},
email: {
type: String
},
createdAt: {
type: Date,
default: Date.now
}
})
I'm working with MongoDB and Node.js
I've tried this:
const people = await Person.aggregate(
[{
$addFields: {
dayyOfWeek: {
$dayOfWeek: "$createdAt"
}
}
}, {
$match: {
dayyOfWeek: {
$eq: req.params.weekday
}
}
}]
)
and tried too with $where and $function in the find function, but it goes wrong because that gives me an error, "MongoError: $where is not allowed in this atlas tier"
I have a blog model:
let blogSchema = new mongoose.Schema({
author: { type: mongoose.Schema.Types.ObjectId, ref: "User" },
title: { type: String, required: true, unique: true },
description: { type: String, required: true, unique: true },
content: { type: String, required: true, unique: true },
likes: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
views: { type: Number, default: 0, required: true },
tags: [],
currentState: { type: String, enum: ['draft', 'published'], required: true, default: 'draft' }}, { timestamps: true });
and a user model which I don't think is necessary to show.
When I try querying for a blog with the author matching a list of userids that the current user is following as such:
let blogs = await Blog.find({ author: { $in: blogIds } })
It gives me the error: CastError: Cast to ObjectId failed for value "{ '$in': [ new ObjectId("6359f421fd4678e2eba3ffee") ] }" (type Object) at path "author" for model "Blog"
How do I get the blogs? I've tried using the $or operator but I would have to loop and it doesn't work anyway. The array values in $in is found correctly as shown in the error, it isn't converting properly though.
The blogids array is [ new ObjectId("6359f421fd4678e2eba3ffee") ]. It is dynamic and is an array of userids that the user follows (OOPS, the name isn't clear)
I think there might be problem in your blogIds array.Try to convert all value inside it with mongoose.Types.ObjectId.
const allIds=blogIds.map(item=>mongoose.Types.ObjectId(item));
Then update your find query.
const blogs = await Blog.find({ author: { $in: allIds } });
I am building an application where user's can save many images along with its name. I want that information to be stored in mongoose in an array. How to do this?
Here is my mealSchema,
const MealSchema = new mongoose.Schema({
userId: {
type: String,
required: true,
},
meals: [
{
mealImg: {
type: String,
},
mealName: {
type: String,
},
},
],
});
how to save data to this schema.
I want the result to be like this :
{ _id: 5fd662b596ac96247463fab8,
userId:"someid"
meals: [
{
_id:23242fff,
mealName:"meal1",
mealImg:"https://meal1.png"
},
_id:23242fff,
mealName:"meal2",
mealImg:"https://meal3.png"
},
_id:23242fff,
mealName:"meal3",
mealImg:"https://meal4.png"
},
] }
You can write smth like this:
Meal.insert({ userId: someId, meals: arrayOfMeals })
But this is not a good practice, because you can put unnecessary and incorrect information in the array. Such problems are solved by intermediate tables and links between them. I advise you to create another table, the scheme of which will be as follows:
const UsersMealsSchema = new mongoose.Schema({
userId: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
mealId: {type: mongoose.Schema.Types.ObjectId, ref: 'Meal'},
});
Then change your Meals shema:
const MealSchema = new mongoose.Schema({
id: {
type: string,
required: true,
}
mealImg: {
type: String,
required: true,
},
mealName: {
type: String,
required: true,
},
});
So my goal is to retrieve posts with comments that are placed today with Mongoose.
First, I create a start-of-the-day UTC current date object with:
const todayForEvent = moment().startOf('day')
.utc().toDate();
this results in 2019-01-02T06:00:00.000Z
then I want to create a DB search with mongoose to fetch the posts where a comment has been placed today
const posts = await Post.find({
// From this user...
$and: [
// Find normal posts that has comments (recent interactions)
{ _posted_by: userId },
{ comments: { $exists: true, $ne: [] } },
{ 'comments.created_date': { $gte: todayForEvent } }
]
})
Third, I have mongoose comment documents that have a property created_date
const CommentSchema = new Schema({
created_date: {
type: Date,
default: moment().utc().toDate()
}
});
const Comment = mongoose.model('Comment', CommentSchema);
module.exports = Comment;
This is the result document after placing a comment
Everything looks OK but for some reason the posts array is still empty after the database search, can someone please tell me what I did wrong
EDIT: added post schema at request
const mongoose = require('mongoose');
const { Schema } = mongoose;
const PostSchema = new Schema({
content: {
type: String,
trim: true
},
_content_mentions: [{
type: Schema.Types.ObjectId,
ref: 'User'
}],
type: {
type: String,
required: true,
enum: ['normal', 'event', 'task']
},
_liked_by: [{
type: Schema.Types.ObjectId,
ref: 'User'
}],
comments_count: {
type: Number,
default: 0
},
comments: [{
type: Schema.Types.ObjectId,
ref: 'Comment'
}],
_group: {
type: Schema.Types.ObjectId,
ref: 'Group',
required: true
},
_posted_by: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
task: {
due_to: {
type: String,
default: null
},
_assigned_to: {
type: Schema.Types.ObjectId,
ref: 'User'
},
status: {
type: String,
enum: ['to do', 'in progress', 'done']
}
},
event: {
due_to: {
type: Date,
default: null
},
_assigned_to: [{
type: Schema.Types.ObjectId,
ref: 'User'
}]
},
created_date: {
type: Date,
default: Date.now
},
files: [{
orignal_name: {
type: String,
default: null
},
modified_name: {
type: String,
default: null
}
}]
});
const Post = mongoose.model('Post', PostSchema);
module.exports = Post;
EDIT 2: sample post document
{ _id: 5c2d14c30176ac30204809a8,
task: { due_to: null },
event: { due_to: null, _assigned_to: [] },
_content_mentions: [],
_liked_by: [],
comments_count: 1,
comments: [ 5c2d14dc0176ac30204809ab ],
content: '<p>poging 5 duust</p>',
type: 'normal',
_posted_by:
{ _id: 5c292e0e63deb43d9434f664,
profile_pic: 'default_user.png',
first_name: 'Jaspet',
last_name: 'Houthoofd' },
_group: 5c292db763deb43d9434f660,
created_date: 2019-01-02T19:45:07.710Z,
files: [],
__v: 0,
liked_by: [] }
**EDIT 3: sample comment **
{ _content_mentions: [],
created_date: 2019-01-02T21:10:04.456Z,
_id: 5c2d28c251f2bd332cdeaf0a,
content: '<p>hehe</p>',
_commented_by: 5c292db763deb43d9434f65f,
_post: 5c2d1dd254ca0429b470f000,
__v: 0 }
So the problem here is that you have two collections, posts and comments. Based on your Posts schema, comments array contains only ids that reference documents that are stored in second collection. That's why you can check whether that array exists and is not empty but you can't refer directly to these elements.
To fix that you can use $lookup to get those documents from comments into posts and then you can apply your date condition inside $match, try:
let posts = await Post.aggregate([
{ $match: { comments: { $exists: true, $ne: [] }, _postedBy: userId } },
{ $lookup: { from: "comments", localField: "comments", foreignField: "_id", as: "comments" } },
{ $match: { 'comments.created_date': { $gte: todayForEvent } } }
])
I have some raw JSON that I have populated for testing purposes, but now I would like to put it into a mongoDB database using mongoDB Compass.
My mongoDB connection string is working and I have working mongoose code.
How do I go about doing this?
I would hope this would be an easy task as mongoDB stores it's data in the form of BSON already.
Here is a snippet of my code.
const json_string =
`[
{
"link": "https://www.youtube.com/watch?v=BMOjVYgYaG8",
"image": "https://i.imgur.com/Z0yVBpO.png",
"title": "Debunking the paelo diet with Christina Warinner",
// ... snip
},
{ // ... snip
The schema is already created:
// for relevant data from google profile
schema.Article = new Schema({
link: { type: String, required: true },
image: { type: String, required: true },
title: { type: String, required: true },
summary: { type: String, required: true },
tag: { type: String, required: true },
domain: { type: String, required: true },
date: { type: String, required: true },
timestamp: { type: Date, default: Date.now }
});
You can use this
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
mongoose.connect(process.env.MONGO_URI);
const articleSchema = new Schema({
link: { type: String, required: true },
image: { type: String, required: true },
title: { type: String, required: true },
summary: { type: String, required: true },
tag: { type: String, required: true },
domain: { type: String, required: true },
date: { type: String, required: true },
timestamp: { type: Date, default: Date.now }
});
const Article = mongoose.model("Article", articleSchema);
const json_string = `[
{
"link": "https://www.youtube.com/watch?v=BMOjVYgYaG8",
"image": "https://i.imgur.com/Z0yVBpO.png",
"title": "Debunking the paelo diet with Christina Warinner"
}
]`;
const jsonBody = JSON.parse(json_string);
for (let i = 0; i < jsonBody.length; i++) {
const data = jsonBody[i];
const article = new Article({
link: data.link,
image: data.image,
title: data.title
//.... rest
});
article.save();
}
Convert JSON string to an array
Loop through each object in the array
Create a new Article instance based on values from the object
Call the save method on the Article object