` "id": 1,
"name": "Afghanistan",
"iso3": "AFG",
"iso2": "AF",
"states": [
{
"id": 3901,
"name": "Badakhshan",
"state_code": "BDS",
"latitude": "36.73477250",
"longitude": "70.81199530",
"type": null,
"cities": [
{
"id": 52,
"name": "Ashkāsham",
"latitude": "36.68333000",
"longitude": "71.53333000"
},
dbo.collection("countries").updateOne(myquery,
{ $set: { "states.$[].cities.$[filter].name": new_name } },
{ arrayFilters: [ {"filter.name":old_city_name} ] },
async function (err, result) {
if (err) {
return res.json({ success: false, response: err.message, statusbar: err })
}
res.json({ success: true, statuscode: 200, response: result });
db.close();
});
trying to update a city name which in the states array its working but its updating every city in that particular state need some help guys
tq all
Related
I am making a simple api which has like document of each post.The like post has array of object of likes of that post.I want to like object into likes only if the document is not exist and if exist remove the object from likes array.I have use element match operator
but it does not work.How can I achieve this.Thanks in advance.
The code is
router.post("/like",(req,res)=>{
likeModel.find({ postId: req.body.postId }, async (err, doc) => {
console.log(req.body.postId)
console.log(doc.length+"s ");
if (!doc.length) {
const like = new likeModel({
postId: req.body.postId,
likes: [
{
userId: userId,
isNotified: isNotified,
},
],
});
await like.save((err, doc) => {
if (err) res.json({ "message": "error" });
else res.json(doc);
});
}
if (err) {
res.json({ "message": "error"});
}
else{
likeModel.find({
postId:req.body.postId,
likes:{
$elemMatch:{
userId:req.body.userId
}
}
},(err,doc)=>{
console.log(doc.length)
if(err){
res.json({"message":"error"})
}
else if(!doc.length){
likeModel.updateOne(
{ _Id: req.body.postId },
{
$push: {
likes:req.body.likes
},
},
(err, doc) => {
if (err) res.json({ "message": "err" });
else res.json(doc);
}
);
}
else{
likeModel.updateOne({
postId:req.body.postId
},{
"$pull":{
"likes":{
"userId":req.body.userId
}
}
},(err,doc)=>{
if(err){
res.json({"message":err})
}
else{
res.json(doc)
}
}
)
}
}
})
})
The document looks like
[
{
"_id": "62f8556861c9b1029e7a07b8",
"postId": "62f5fb7d74033aeac1e06399",
"likes": [
{
"userId": "62f5d6bee2310e3c71e10e36",
"isNotified": true,
"_id": "62f8556861c9b1029e7a07b9"
},
{
"userId": "62f5d9c2b30ecc8ca84c0242",
"isNotified": true,
"_id": "62f865ed2a055ef17214a6ea"
},
{
"userId": "62f5d9c2b30ecc8ca84c0242",
"isNotified": true,
"_id": "62f866192a055ef17214a6f1"
},
{
"userId": "62f5d9c2b30ecc8ca84c0242",
"isNotified": true,
"_id": "62f8668c5ca6a649fc89cc3b"
},
{
"userId": "62f5d9c2b30ecc8ca84c0242",
"isNotified": true,
"_id": "62f866b3c2041b73ea8d9d8a"
},
{
"userId": "62f5d9c2b30ecc8ca84c0242",
"isNotified": true,
"_id": "62f867b6545168c7cd377b17"
},
{
"userId": "62f5d9c2b30ecc8ca84c0242",
"isNotified": true,
"_id": "62f868cf3255b839e1ca047b"
}
],
"__v": 0
},
{
"_id": "62f866192a055ef17214a6ed",
"postId": "62f5fb7e74033aeac1e0639d",
"likes": [
{
"userId": "62f5d9c2b30ecc8ca84c0242",
"isNotified": true,
"_id": "62f866192a055ef17214a6ee"
}
],
"__v": 0
}
]
[
"id": 1,
"name": "Afghanistan",
"iso3": "AFG",
"iso2": "AF",
"states": [
{
"id": 3901,
"name": "Badakhshan",
"state_code": "BDS",
"latitude": "36.73477250",
"longitude": "70.81199530",
"type": null,
"cities": [
{
"id": 52,
"name": "Ashkāsham",
"latitude": "36.68333000",
"longitude": "71.53333000"
},]
let filter = { iso2: country_code ,name:country_name,"states.state_code":state_code,"states.name":state_name };
let newvalues = { $push:
{"states.$[].cities": [{ name: state_name, code:city_code }]}}
dbo.collection("countries").updateOne(filter, newvalues,{upsert:true}, async function (err, result) {
if (err) {
res.json({success:false, response: err.message,statusbar:err})
}
res.json({success: true, statuscode: 200, response: result})
db.close();
Hi all I am trying to add,delete and update city which is as object inside a states array i tried as above did not workout need a suggestion tqq
I have the following schema and I'm trying to update the heart_rates and glucose_levels arrays by adding a new entry:
"days": [
{
"day": "16-12-2020",
"data": {
"average_score": 80,
"metabolic_score": 80,
"cardio_score": 80,
"heart_rates": [{
"start_date": "timestamp",
"end_date": "timestamp",
"value": 100
}],
"glucose_levels": [{
"start_date": "timestamp",
"end_date": "timestamp",
"value": 100
}],
"weekly_health_recap": {
"id": "",
"start_date": "timestamp",
"end_date": "timestamp",
"rating": "Excellent"
},
"summaries": [{
"type": "meal",
"actions": [
"sweets", "fruits"
],
"title": "",
"start_date": "",
"end_date": ""
}],
"articles": [{
"id": "",
"name": "",
"text": "",
"image_url": ""
}]
}
}
]
I tried various solutions, however they didn't give the expected results.
Currently, I'm using the following code to find if there is an existing entry for the day, if there is not, I'm creating it using findByIdAndUpdate and upsert, if there is already a day entry then I'm using update and push to add a new entry in the heart_rates array. The problem is that the update inserts the new entry in some other day entry and not the one that I'm querying for.
exports.updateDayHeartrate = async (req, res) => {
User.find({ "_id": req.body._id, "days.day": req.body.day}, function (err, docs) {
if (err){
return done(err);
}
if (docs.length > 0) {
User.update({"_id": req.body._id, "days.day": req.body.day},
{$push: {"days.0.data.heart_rates": req.body.data}},
(err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}
else if (user) {
res.status(200).send("Updated!")
}
}
)
}
else{
User.findByIdAndUpdate(req.body._id,
{$push: {"days": {"day": req.body.day, "data": {"heart_rates": req.body.data}}}},
{upsert:true, new:true, setDefaultsOnInsert: true},
(err, user) => {
if (err) {
res.status(500).send({ message: err });
return;
}
else if (user) {
res.status(200).send("Updated!")
}
}
);
}
});
};
I need to find my data that matches the particular type. Say, I have an array of objects in my DB, with each object having it's leadType : all or leadType: blacklist. Each object has a different kind of leadType value associated with it.
I want to get the complete data that matches the particular leadType, like leadType: 'radar'.
I tried using the following query but along with the documents it matches, it also returns the empty documents that do not matches the specified projection.
This is what I tried:
exports.leads_by_type = (req, res) => {
const { lead_type } = req.body;
Lead.find({}, { leads: { $elemMatch: { leadType: lead_type }}} )
.then(data => {
if (!data || data.length === 0) {
return res.status(404).json({ message: "No data found" });
}
res.status(200).json({ message: "Data found", data });
})
.catch(err => res.status(500).json({ err }));
};
and it returns me the output as follows:
{
"message": "Data found",
"data": [
{
"_id": "5e83427079f7611bdc1e48a0",
"leads": [
{
"education": {
"school": "happy kids corner",
"graduation": "some school"
},
"currentPosition": {
"title": "Salesforce developer",
"endDate": "currently working",
"employmentType": "full-time",
"industry": "information technology"
},
"location": {
"state": "delhi",
"country": "india"
},
"leadType": "radar",
"name": "Ben",
"mobile": 1524524678,
"_id": "5e83427079f7611bdc1e489e"
}
]
},
{
"_id": "5e84cb4fb59fdd1644e7c226",
"leads": [
{
"education": {
"school": "happy kids corner",
"graduation": "some school"
},
"currentPosition": {
"title": "Salesforce developer",
"endDate": "currently working",
"employmentType": "full-time",
"industry": "information technology"
},
"location": {
"state": "delhi",
"country": "india"
},
"leadType": "radar",
"name": "joey",
"mobile": 1524524678,
"_id": "5e84cb4fb59fdd1644e7c224"
}
]
},
{
"_id": "5e84cb70b59fdd1644e7c229",
"leads": []
},
{
"_id": "5e84cb88b59fdd1644e7c22c",
"leads": []
},
{
"_id": "5e84cbb7b59fdd1644e7c232",
"leads": []
},
{
"_id": "5e84cbd9b59fdd1644e7c235",
"leads": [
{
"education": {
"school": "happy kids corner",
"graduation": "some school"
},
"currentPosition": {
"title": "Salesforce developer",
"endDate": "currently working",
"employmentType": "full-time",
"industry": "information technology"
},
"location": {
"state": "delhi",
"country": "india"
},
"leadType": "radar",
"name": "rhea",
"mobile": 1524524678,
"_id": "5e84cbd9b59fdd1644e7c234"
}
]
}
]
}
Please help me out to fix remove these empty objects from the data output
Edit: Adding my DB screenshot:
If you want to match only the documents with leadType equals to radar you should specify this in the find condition.
exports.leads_by_type = (req, res) => {
const { lead_type } = req.body;
Lead.find({ 'leads.leadType': lead_type })
.then(data => {
if (!data || data.length === 0) {
return res.status(404).json({ message: "No data found" });
}
res.status(200).json({ message: "Data found", data });
})
.catch(err => res.status(500).json({ err }));
};
find({ leads: { $elemMatch: { leadType: lead_type }}} )
You can try the above query.
{} you had used empty object along with your condition in find which is the root cause behind the fetched empty data.
I'm fairly new to mongoose and I am trying to write a query that just returns a subdocument within my main document.
My document structure is like this:
PROFILE
- CONTACTS [ARRAY]
I've written the following endpoint to return one contact, where I pass the profile id and the id of the subdocument:
"/:owerId/getcontact/:contactId"
My Express function code looks like this:
router.route('/:ownerId/getcontact/:contactId')
.get(function(req, res){
Profile.findOne({'owner_id':req.params.ownerId}).then(function(err, profile){
if(err)
res.send(err);
profile.findOne({'_id':req.params.contactId}).then(function(err, contact){
if(err)
res.send(err);
res.json(contact);
})
})
})
But this code returns the whole profile.
When I try to get by ID it does the same thing. Here is my code and just below that is the entire profile that is returned:
router.route('/:ownerId/getcontact/:contactId')
.get(function(req, res){
Profile.findById(req.params.ownerId).then(function(err, profile){
if(err)
res.send(err);
var data = profile.contacts.id(req.params.contactId);
res.json(data);
})
})
{
"_id": "5886e3692ca4542c453431ee",
"initial": "u",
"last_name": "randal",
"first_name": "chris",
"owner_id": "5886e32c2ca4542c453431ed",
"__v": 1,
"contacts": [
{
"last_name": "Eltoro",
"first_name": "Peter",
"_id": "5886e3f5a219472cac886a9f",
"businesses": [],
"addresses": [],
"phones": [
{
"phone_type": "mobile",
"phone_number": "555-555-999",
"_id": "5886e3f5a219472cac886aa2"
},
{
"phone_type": "home",
"phone_number": "999-876-000",
"_id": "5886e3f5a219472cac886aa1"
}
],
"emails": [
{
"email_address": "tim#time.com",
"_id": "5886e3f5a219472cac886aa0"
}
]
},
{
"college": "University of WA",
"highschool": "Kalaheo",
"birthday": "1990-12-22T08:00:00.000Z",
"last_name": "Smith",
"first_name": "Suzanne",
"_id": "5886fb7fac288c2e31eabe0a",
"businesses": [],
"addresses": [
{
"zip": "98777",
"state": "WA",
"city": "Seattle",
"address_2": "Apt 234",
"address": "124 194th St. SW",
"_id": "5886fb7fac288c2e31eabe0e"
}
],
"phones": [
{
"phone_type": "mobile",
"phone_number": "206-899-9898",
"_id": "5886fb7fac288c2e31eabe0d"
},
{
"phone_type": "home",
"phone_number": "206-789-0987",
"_id": "5886fb7fac288c2e31eabe0c"
}
],
"emails": [
{
"email_type": "personal",
"email_address": "suzanne#smith.com",
"_id": "5886fb7fac288c2e31eabe0b"
}
]
},
{
"last_name": "Alabaster",
"first_name": "Cindy",
"_id": "5888b0bd3c025e54476828d9",
"businesses": [],
"addresses": [],
"phones": [
{
"phone_type": "home",
"phone_number": "999-999-0909",
"_id": "5888b0bd3c025e54476828dc"
},
{
"phone_type": "home",
"phone_number": "000-000-0000",
"_id": "5888b0bd3c025e54476828db"
}
],
"emails": [
{
"email_address": "Some#them.com",
"_id": "5888b0bd3c025e54476828da"
}
]
}
],
"businesses": [],
"addresses": [],
"phones": [
{
"phone_number": "999-999-9999",
"phone_type": "mobile",
"_id": "5886e37f2ca4542c453431ef"
}
],
"emails": []
}
Mongoose sub documents have special methods to retrieve them:
router
.route('/:ownerId/getcontact/:contactId')
.get(function(req, res) {
Profile.findOne({ owner_id: req.params.ownerId }, function(err, profile) {
if ( err ) {
res.send(err);
}
var contact = profile.contacts.id(req.params.contactId);
res.json(contact);
});
});
See Mongoose Sub Documents.
Another route is through the aggregation framework where you can use the $match, $arrayElemAt and $filter operators to return the data you want.
Consider running the following aggregate operation in your API endpoint implementation:
router.route('/:ownerId/getcontact/:contactId')
.get(function(req, res){
var ownerId = mongoose.Schema.Types.ObjectId(req.params.ownerId),
contactId = mongoose.Schema.Types.ObjectId(req.params.contactId);
Profile.aggregate([
{ "$match": { "owner_id": ownerId } },
{
"$project": {
"contact": {
"$arrayElemAt": [
{
"$filter": {
"input": "$contacts",
"as": "contact",
"cond": { "$eq": ["$$contact._id", contactId] }
}
},
0
]
}
}
}
]).exec(function(err, profile){
if(err) res.send(err);
res.json(profile[0].contact);
})
})