mongoose find x docs for specific filed - node.js

I have a collection of videos, each video doc has user_id.
I need to get the last 5 videos of each user.
don't know where to start... tried grouping without any success.
any help would be appreciated.

give this pipeline a try:
db.collection.aggregate([
{
$sort: { _id: -1 }
},
{
$group: {
_id: "$user_id",
videos: { $push: "$$ROOT" }
}
},
{
$project: {
_id: 0,
user_id: "$_id",
videos: { $slice: ["$videos", 5] }
}
}
])
https://mongoplayground.net/p/6NOOJDnfIhk
explanation:
with the first stage, you $sort the whole collection in descending order on the _id field. sorting initially is necessary because there's no operator in mongo that can sort the grouped items afaik.
then you group by user_id field. we $push all documents of each group to a new field called videos. $$ROOT variable gives you access to all docs of each group.
the final $project stage uses $slice to pick only the top 5 items in the videos array from the previous stage and sets it on a field of the same name.

Related

how to populate to an array inside another shema using mongoose

There are two collections. Catalog collection and order Collection. Catalog collection contains seller id , and compelete product details.
Order collection contains order details like ids of ordered products and buyer details.
My problem is how can I get the complete product details when fetching an order .
order collection is given below
this is the order collection. It contains product Id. I need to get the details of products when fetching orders. Problem is that there is no seperate collection for products. Products are present inside 'catalog' collection
Catalog Collection is given below:
this is the catalog collection.It contains an array of products. so the products are present there
I need to get product details when fetching order details
const order = await Order.find().populate("products");
I am not sure I understand your question entirely but hope should help you:
Plan
unwind products
lookup product with _id of product in catalog.products
unwind the lookup result because result of lookup stage is an array
group this back together
Implementation
const result = await orderModel.aggregate()
.unwind('products')
.lookup({
from: 'catalogs',
let: { product_id: '$products' }, // in order
pipeline: [
{
$unwind: '$products' // $expr cannot digest arrays so we need to unwind which hurts performance...
},
{
$match: { $expr: { $eq: ['$products._id', '$$product_id'] } }
},
{
$project: { _id: 0, products: 1 } // only care products in catelog
}
],
as: 'productDetail'
})
.unwind('productDetail')
.group({
_id: '$_id',
seller: { '$first': '$seller' },
buyer: { '$first': '$buyer' },
products: {
$push: '$productDetail.products'
}
});
However, I don't recommend doing it this way as it can be resource intensive... I suggest you change your database design eg separating product into a separate collection for easier querying.

Calculating sum of field in all matching documents - MongoDB - Mongoose

I'm trying to write a Mongoose aggregation query to get the sum of a field for all matching documents.
Meaning I have a model that looks like:
{
itemNumber: String,
quantity: Number
}
There are multiple documents with the same itemNumber, I'm looking to get the sum of the quantity fields.
What's the easiest way to do this?
use group
db.collection.aggregate([
{
$group: {
_id: "$itemNumber",
count: {
$sum: "$quantity"
}
}
}
])
mongoplayground

MongoDB: How to perform a second match using the results (an array of ObjectIds) of the previous match in aggregation pipeline

I have a MongoDB collection called users with documents that look like:
{
_id: ObjectId('123'),
username: "abc",
avatar: "avatar/long-unique-random-string.jpg",
connections: [ObjectId('abc'), ObjectId('xyz'), ObjectId('lmn'), ObjectId('efg')]
}
This document belongs to the users collection.
What I want to do:
First, find one document from the users' collection that matches _id -> '123'.
Project the connections field received from step 1, which is an array of ObjectIds of other users within the same collection.
Find all documents of users from the array field projected in step 2.
Project and return an array of only the username and avatar of all those users from step 3.
While I know that I can do this in two separate queries. First using findOne which returns the friends array. Then, using find with the results of findOne to get all the corresponding usernames and avatars.
But, I would like to do this in one single query, using the aggregation pipeline.
What I want to know, is it even possible to do this in one query using aggregation?
If so, what would the query look like?
What, I currently have:
await usersCollection
.aggregate([
{ $match: { _id: new ObjectId(userId) } },
{ $project: { ids: "$connections" } },
{ $match: { _id: { $in: "ids" } } },
{
$project: {
username: "$username",
avatar: { $ifNull: ["$avatar", "$$REMOVE"] },
},
},
])
.toArray()
I know this is wrong because each aggregation stage receives the results from the previous stage. So, the second match cannot query on the entire users' collection, as far as I know.
I'm using MongoDB drivers for nodeJS. And I would like to avoid $lookup for possible solutions.

Nestjs- How to sum up all the number values of a particular collection of mongodb

I am working on nestjs and I have a collection where 5 documents are saved and each document has a property name 'price'. I want to fetch price property from every document and need to sum up all and shows that sum as an output. How do I achieve this?
Use aggregate
.aggregate([
{
$group: {
_id: '',
sumPrices: { $sum: '$price' }
}
])

how can i agregate datas from different collections in mongodb using nodejs?

I am using mongoDB and nodejs
I have 4 collections
collection 1 is teacher with fields teacher_id, teacher_name
collection 2 is subject with fieldssubject _id, subject_name
collection 3 is book with fields book_id, book_name
collection is student which have fields -- _id, student_name, teacher_id, subject_id, book_id
how can I fetch ids from 1, 2, 3 collections simultaneously and insert to corresponding id in collection
I have tried some which always ask for a matching field... is ther any function which returns data from collection even though no match field?
can someone please help
Well, in that case, you need to fetch all the documents from those collections. That will be a bit costly aggregation but I'm adding here in code:
Firstly, I'm grouping on null, to avoid to attach lookup value to every single document in teacher collection.
db.teacher.aggregate([
{
$group:{
"_id":null,
"root":{
$push:"$$ROOT"
}
}
},
{
$lookup:
{
from:"subject",
pipeline: [],
as: "subjectLookup"
}
},
{
$lookup:
{
from:"book",
pipeline: [],
as: "bookLookup"
}
},
{
$lookup:
{
from:"student",
pipeline: [],
as: "studentLookup"
}
}
]).pretty()
These lookups will give the array which contains all the documents from respective collections, you can limit the documents by adding $match stage in the pipeline of lookup stage.
Hope this will solve your problem :)

Resources