MongoDb find all objects that contain nested value - node.js

This is my user object sent as token in req:
{
"_id": "6212aba16653621e67393549c",
"name": "User",
"email": "user#gmail.com",
"__v": 0
}
This is my get function code:
const getSharedLists = asyncHandler(async (req, res) => {
const lists = await List.find({
sharedWith: { email: req.user.email },
});
res.status(200).json(lists);
});
This is what object looks like:
{
"_id": "621817233300dfff68e23710",
"user": "6212ab33383621e67393549c",
"listName": "test update",
"private": true,
"items": [
{
"itemName": "Bananas",
"quantity": 3,
"isBought": false,
"isle": "isle",
"_id": "621b043622147906eece2e72"
},
],
"sharedWith": [
{
"email": "user#gmail.com",
"_id": "621bdbf0791a322534284c49"
}
],
"createdAt": "2022-02-24T23:39:25.668Z",
"updatedAt": "2022-02-27T21:21:03.584Z",
"__v": 0,
},
I keep getting empty array back, even when hard code req.user.email as "user#gmail.com" for example. I need to find all lists on MongoDb that have my email in array of sharedWith.
Can somebody help please. Apparently I'm using List.find method wrong but can't seem to figure out the syntax.

You need (.) dot notation.
const lists = await List.find({
"sharedWith.email" : req.user.email
});
Sample Mongo Playground
Reference
Specify a Query Condition on a Field Embedded in an Array of Documents

Related

Find a document by an object id in that doc in mongoDB node js express js

Hey this i want to fetch the products of a certain user so i added the user in the model by Object id , but when i was setting the router callBack function i didn't know how to do it !
{
"_id": {
"$oid": "62f250d3e2533cf4ca2ad7f3"
},
"image": "https://eshop-server.herokuapp.com/public/uploads/Surface-Pro-7-128GB-1604665289664.png",
"brand": "ASUS",
"price": {
"$numberInt": "250"
},
"rating": null,
"numReviews": null,
"isFeatured": false,
"name": "Surface Pro 7 128GB",
"description": "Tablet PC - Intel Core i3 1005G1 Ice Lake, touchscreen 12.3\" IPS 2736 × 1824, RAM 4GB LPDDR4X, Intel UHD Graphics",
"category": {
"$oid": "5f15d54cf3a046427a1c26e3"
},
"user": {
"$oid": "62f0e99be78e33cc5662d1f4"
},
"reviews": [{
"avatar": "https://pbs.twimg.com/profile_images/1760228143/Vetor-Johnny-Bravo-Vetorizado-Corel_400x400.jpg",
"name": "Johnny Bravo",
"review": "Amazing experience all around"
}, {
"avatar": "https://vignette.wikia.nocookie.net/asterix/images/3/3c/Asterix.png",
"name": "Asterix",
"review": "It's very hard. Only managed with resource to magic potion"
}, {
"avatar": "https://vignette.wikia.nocookie.net/looneytunes/images/7/7f/Coyote.gif",
"name": "Wild Coyote",
"review": "All my trickery and tools paid of. Thank ACME for suggesting this product to me"
}],
"countInStock": {
"$numberInt": "8"
},
"__v": {
"$numberInt": "0"
},
"richDescription": "eatures a detachable keyboard and offers the comfort of a classic laptop as well as the convenience of a tablet.&nbsp",
"images": ["http://localhost:3000/public/uploads/5f15d8852a025143f9593a7c-1604665316399.png", "http://localhost:3000/public/uploads/5f15d8852a025143f9593a7c-1604665316400.jpeg"]
}
as You can see the user object id is included so how can i find it ! this i what i tried but it didn't work
router.get(`/:id/products`, async (req, res) => {
const productList= await Product.find({user.$oid:req.params.id}).populate("user");
if (!productList) {
res.status(500).json({ success: false });
}
res.send(productList);
});
Solution
Replace Product.find({user.$oid:req.params.id})
with Product.find({user._id: mongo.ObjectId(req.params.id)})
Explanation
$oid is a way to represent ObjectId in JSON. $oid is not a property that exists on the document. We need to convert the id received in request to an ObjectId and match it with the _id field of the document.
Further
Wrap the conversion into a try/catch or something similar. Converting a string to an ObjectId can fail if the string is not a proper representation of an ObjectId.
const mongo = require('mongodb');
let idAsObjectId;
try {
idAsObjectId = mongo.ObjectId(req.params.id)
} catch (err) {
// handle error
}

How to sort for properties inside an other object in mongoose

I have this document and I want to sort the other documents based on the views.
{
"info": {
"title": "Hello",
"views": 500,
"cover": "https:----",
"duration": 203,
"album": true,
"lyrics": "---"
},
"_id": "62bb107c70a37ead49d685f8",
"userName": [
"Ben",
"Mike"
],
"audio": "---",
"__v": 0
},
This is my sorting code at the moment:
const song = await Song.find({}).sort({ views: 1 }).limit(10)
This code is not working I am getting back unordered documents.
Since the views field is inside info object, you have to use { "info.views": 1 }. This should give you the desired result.
const song = await Song.find({}).sort({ "info.views": 1 }).limit(10)

How to update a value inside mongodb with nodeJS?

I'm trying to update a value inside mogoodb array but is the problem
database?
"TempChannels": [{
"user": "299481590445113345",
"channel": "794869948878159884",
"settings": []
}, {
"user": "583363766750806043",
"channel": "795004103998308352",
"settings": []
}],
The part of the code that should update the user:
Data.TempChannels[0].user = Target.id
Data.save().catch(er => console.log(er))
Also, no error appears when I run the code. and when i console the data it returns a user which has updated but it is not actually saved in mongodb!
code
Data.save().then(() => console.log(Data.TempChannels[0].user))
this is the whole data
{
"_id": {
"$oid": "5ff0cd1ee3d9fd2d40d82d23"
},
"TempChannels": [{
"user": "299481590445113345",
"channel": "795014692522295326",
"settings": []
}, {
"user": "583363766750806043",
"channel": "795015273060892753",
"settings": []
}],
"Guild": "704158258201624657",
"Stats": "true",
"ChannelID": "795014681664290826",
"ParentID": "795014680556994610",
"LogChannelID": "795014683601010709",
"TempControlChannelID": "795014682518749274",
"DefaultSettings": {
"limit": null,
"name": null,
"bitrate": null,
"copyperms": null
},
"__v": 2
}
I'm filtering the data by Guild
if you are using mongoose to connect MongoDB, the
Use markModified("updated field name")
Data.TempChannels[0].user = Target.id
Data.markModified('TempChannels');
Data.save().catch(er => console.log(er))
if you are using mongoose, there is a method that will allow to update the content of existing data
const res = await Person.replaceOne({ _id: 24601 }, { name: 'Jean Valjean' });
res.n; // Number of documents matched
res.nModified; // Number of documents modified
If you are using Mongoose, you can update the record by doing something similar to this:
SchemaName.update({Guild: 'Guild Value Here'}, {$set: { "TempChannels[0].user" : "%newvalue%"}})
.then((data) => {
console.log(data)
})
.catch(err => {
console.log.error(err);
});
You should replace schemaName with the name of your schema if you are using mongoose, and in case you are not using it, I think it would be better for you to start using it.

Find data of those where referenced object id equals to user._id

I am getting all the order details
For example:(example of one order)
{
"customer": {
"id": "5db6ac89d85a2c1c709a42da",
"name": "Testing"
},
"product": {
"id": "5dba78427af9e73b18bdbb22",
"name": "image",
"seller": "Testing",
"price": 100,
"imgurl": "ok"
},
"_id": "5dba788fdeb78931f8a30105",
"quantity": 3
}
When I use find() I get all the elements but I only want to show the data of the one who is logged in
i.e where customer.id equals to req.user._id
I am using find() as shown in the code below:
router.get('/cart',verifyToken, async (req, res)=>{
const order = await Order.find({/* what should be the query here to get the desired result*/},'product , quantity , customer ');
try{
res.send(order)
}catch(err){
res.status(400).send(err);
}});
Any other methods to achieve this
You have to use findOne().Like below
const order = await Order.findOne({'customer.id':req.user._id}) // probably req.body.user._id
or
await Order.findOne( { customer: { id:req.user._id } } )
See the docs here

REST API using Nodejs Mongoose Express

{
"_id": "58be5a4a031372098578b1d6",
"name": "A",
"email": "abc#gmail.com",
"username": "A.a",
"password": "$2a$05$GAF1hP91EowKUTKr14ASL.MRd2lOjotfOgVlEghwnqctNcIe5seNW",
"latitude": 12,
"longitude": 72,
"profilePic": "images/A.png",
"__v": 9,
"isBuddyEnabled": true,
"friendRequests": [
{
"friendId": "58be7aa0c204cb134068975d",
"isAccepted": true
},
{
"friendId": "58bf8cb4c26d5811b188a600",
"isAccepted": false
}
],
"friends": [
"58be7aa0c204cb134068975d"
],
"networkContacts": [
{
"profession": "doctor"
}
],
"interests": [
"sports",
"music"
]
}
I have the above json for a single user , now i need the array of such json with all info whose friendRequest isAccepted is false which means these requests are pending for him,
for eg: when i hit api/requests/58be5a4a031372098578b1d6 => i have to get info of id 58bf8cb4c26d5811b188a600
till now i was able to retreive the ids whose request was not accepted via following query
app.post('/api/users/requests/:id'function(req,res){User.find({"_id":req.params.id})
.find({"friendRequests.isAccepted":false},function(err,callback){}})
You can use array filter to pop out the subdocument in array based on the filter
User.find({"_id":req.params.id}, function (err, user) {
var friendRequests = user.friendRequests.filter(function (fr) {
return fr.isAccepted == false;
}).pop();
console.log(friendRequests); //logs { "friendId": "58bf8cb4c26d5811b188a600", "isAccepted": false
});

Resources