I have a getPosts controller on my Post Controller, my goal is to sort it by the createdAt time to maintain order because when I map it on the frontend it starts from the last created to the latest.
const getPosts = asyncHandler(async (req, res) => {
const posts = await Post.find().sort([createdAt, 1]);
res.json(posts);
});
sort() can't take arrays it either takes string or an object
const posts = await Post.find().sort({createdAt: 1});
also you can use " asc "," ascending " instead of 1.
You can use mongo query sort() to get that. It can take value 1 or -1 according to sorting order, you can read mongo db document for more here.
Also you can put this sort query in timestamp of these for getting this too.
//Sorting by descending order
const posts = await Post.find().sort({ createdAt: -1 })
//Sorting by ascending order
const posts = await Post.find().sort({ createdAt: 1 })
So you can do this:
const getPosts = asyncHandler(async (req, res) => {
const posts = await Post.find().sort({ createdAt: 1 })
res.json(posts)
})
sort() takes in either an Object or a String.
the correct syntax should be
const posts = await Post.find().sort({createdAt: 1});
Related
I have a little question
I try to sort with mongoose I know the simple way
but I dont know how to do that with data I get in req.body lets say.
I add here a code I try
exports.sortBy = async (req, res, next) => {
const data1 = req.body.data1 //the data i want to sort
const sortBy = req.body.sortBy //sory by price,createdAt,length and more
const downUp = req.body.downUp // 1, -1
console.log(sortBy)
console.log(data1)
const data = await Book.aggregate([
{
$sort: { [sortBy]: downUp }
},
])
res.status(200).json({
status: 'success',
results: data.length,
data
})
}
so I can sort by the data I get in req.body
Try the following:
const data = await Book.sort({sortBy: downUp});
which seems to work and is much easier to read.
My goal is to get the one product object back depending on the product id i marked in green (out of the whole products array in my mongo DB)
My Backend entry looks as follows:
router.get("/:id", async (req, res)=> {
const mid=req.params.id;
console.log(mid)
const products = await Product.findOne({ id: mid })
console.log(products)
if (products) {
res.send(products);
} else {
res.status(404).send({message:"product not found"})
}
});
Connsole.log(mid) on line three works and it gives the right id back. However when i try to filter that one array depending on the value in line three i always get back the first object of my Database, which is the gopro camera, instead of the right object.
The Output looks as Follows:
632834528
{
_id: '5f9849daf641a82b257d529b',
id: 3484,
agentId: 66343,
title: 'GoPro Camera',
slug: 'gopro',
What am i doing Wrong?
I tried const products = await Product.find({ id: mid }) as well, but it gives me the whole array back instead of just the one object.
I think it's returning a Query. Try:
const products = await Product.findOne({ id: mid }).exec();
This solution worked for me:
I have to use the Expressasynchandler like this:
Edit: This solution might not be the best (see comments on answer above)
router.get("/:id", expressAsyncHandler(async (req, res) => {
const mid=req.params.id;
const products = await Product.findOne({ id: mid })
if (products) {
res.send([products]);
} else {
res.status(404).send({message:"product not found"})
}
}));
I'm using API routes in Next.js with sample data from MongoDB. I am trying to return the data from a single object. First time working with MongoDB, so apologies if the answer has been staring me in the face.
I'm getting an empty array returned with the following query:
import { connectToDatabase } from '../../../util/mongodb';
export default async (req, res) => {
const { db } = await connectToDatabase();
const movies = await db
.collection("movies")
.find({ "_id": "573a1395f29313caabce1f51" })
.limit(20)
.toArray();
res.json(movies);
};
Which corresponds to an object like this:
{
"_id": "573a1395f29313caabce1f51",
"fullplot": "some text goes here"
}
What am I missing? Shouldn't .find({_id: "573a1395f29313caabce1f51"}) return that information? Why am I only seeing an empty array? I understand why it's returning an array (I added .toArray()), but that shouldn't impact whether the results are returned or not.
For what it's worth, querying without parameters works properly. No issues with this query:
import { connectToDatabase } from '../../util/mongodb';
export default async (req, res) => {
const { db } = await connectToDatabase();
const movies = await db
.collection("movies")
.find({})
.sort({ metacritic: -1 })
.limit(20)
.toArray();
res.json(movies);
};
Any help is appreciated, thanks in advance!
Needed to cast to an objectID as mentioned in the comments.
https://docs.mongodb.com/manual/reference/operator/aggregation/toObjectId/
For example I want to update a mongoose document in a put request, I have to do this:
app.put('/update', async(req,res) => {
try{
const product = await Product.findById(req.body.id)
product.name = req.body.name
product.price = req.body.price
procut.discount = req.body.discount
// etc...
await product.save()
res.json(product)
}catch(e){
res.json({message: "Error updating the product"})
}
})
I'm asking if there is another faster and developer friendly way of updating products instead of typing each of the document properties and equal them to the req.body.[property]?
You can try the following for object merging
Object.assign(product, req.body)
note: i haven't tried with mongoose collection
You can use updateMany or findOneAndUpdate model methods, but it is more advisable to use .save()
https://mongoosejs.com/docs/api.html#model_Model.updateMany
https://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate
If you want to .save() to look cleaner, you can do like this:
async updateEntity(payload) {
const keysToUpdate = Object.keys(payload)
if (keysToUpdate.length === 0) {
throw new Error('Update payload must not be empty!')
}
const entity = await entityModel.findOne({ _id: redirect })
keysToUpdate.forEach((key) => {
entity[key] = payload[key]
})
await entity.save()}
I am trying to query a Firestore sub collection in an ionic 4 app/angular app. My database looks as follows people(id) ----> tasks(id)
{ description : this is a description about a cat,<br>
title: this is a cat <br>
category: cat }
I am using a Firestore function to query all of the data in the collection. This is what the Firestore function looks like:
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin'
admin.initializeApp()
export const getFeed = functions.https.onCall(async (req,res) =>{
const docs = await
admin.firestore().collection('people').limit(5).get()
return docs.docs.map(doc => {
return {
postID: doc.id,
...doc.data()
}
})
})
the typescript home.ts file looks like this :
const getFeed = this.aff.httpsCallable('getFeed')
this.posts = getFeed({}).subscribe(data=> {
console.log(data)
// this.posts = data
})
}
I've tried to use the array-contains option to query, but it doesn't
work. The array shows up empty on the console.
export const getFeed = functions.https.onCall(async (req,res) =>{
const docs = await
admin.firestore().collection('people').where("category",
"array-
contains", "cat").limit(5).get()
return docs.docs.map(doc => {
return {
postID: doc.id,
...doc.data()
}
})
})
It's not very clear from your question, but it looks like the category field of your database isn't actually a list type field. array-contains only works if the value is a list, not if it's just a single string value. If it's just a string, then use a == filter on it.
I have found workaround by adopting array field type instead of subcollection.
Here is an example of my code:
var coll = this.firestore.collection('credentials', ref => ref.where('tags', 'array-contains-any', ['agile']).orderBy('shortName')); // selects part of collection where roomId = roomStripped, sorted by name
return coll.snapshotChanges();
I have main collection called credentials, and a list of tags in each document.