How to prevent update function insert to the MongoDB from Meteor? - javascript

I have the Meteor.method that check the existing document.
when it does not found it insert the document,
for second time it found it update and insert.
Please help to check and fix my following code:
'upload': function upload(data, name, eventId) {
const wb = XLSX.read(data, {type:'binary'});
var checkUpdate;
XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]).forEach(r => {
r.owner = this.userId,
r.username = Meteor.user().username,
r.updatedAt = new Date(),
r.amount = Number(r.amount),
r.eventid = eventId,
r.firstname = r.firstname.trim(),
r.lastname = r.lastname.trim(),
Registers.findOne({ firstname: r.firstname, lastname: r.lastname, eventid: eventId }) ?
Registers.update({ firstname: r.firstname, lastname: r.lastname, eventid: eventId }, { $set: {updatedAt: r.updatedAt, amount: r.amount } })
:
r.createdAt = new Date(),
Registers.insert(r)
})
return wb;
},
First time, if the database is empty, it insert new document.
For second time, if it found the document it then update the document,
and also insert new document with update function not insert function.
meteor:PRIMARY> db.registers.find({ eventid: "aZrumf45q8sBGGrY2" })
{ "_id" : "MzqD73vsgyxRTyekJ", "salution" : "Mr.", "firstname" : "qwer", "lastname" : "asdf", "gender" : "Male", "age" : "38", "province" : "chiangmai", "amount" : 1000, "owner" : "rBjWm4PRTHwAo2vRS", "username" : "mai", "updatedAt" : ISODate("2017-09-11T12:28:36.966Z"), "eventid" : "aZrumf45q8sBGGrY2", "createdAt" : ISODate("2017-09-11T12:20:49.731Z") }
{ "_id" : "suzPhYkvQQcYjZj5p", "salution" : "Mr.", "firstname" : "abcd", "lastname" : "efgh", "gender" : "Male", "age" : "30", "province" : "chiangmai", "amount" : 500, "owner" : "rBjWm4PRTHwAo2vRS", "username" : "mai", "updatedAt" : ISODate("2017-09-11T12:28:37.017Z"), "eventid" : "aZrumf45q8sBGGrY2", "createdAt" : ISODate("2017-09-11T12:20:49.739Z") }
{ "_id" : "QYgF7aLvBDwo5amuA", "salution" : "Mr.", "firstname" : "qwer", "lastname" : "asdf", "gender" : "Male", "age" : "38", "province" : "chiangmai", "amount" : 1000, "owner" : "rBjWm4PRTHwAo2vRS", "username" : "mai", "updatedAt" : ISODate("2017-09-11T12:28:36.966Z"), "eventid" : "aZrumf45q8sBGGrY2" }
{ "_id" : "XYSBxgiz5T9QXad6r", "salution" : "Mr.", "firstname" : "abcd", "lastname" : "efgh", "gender" : "Male", "age" : "30", "province" : "chiangmai", "amount" : 500, "owner" : "rBjWm4PRTHwAo2vRS", "username" : "mai", "updatedAt" : ISODate("2017-09-11T12:28:37.017Z"), "eventid" : "aZrumf45q8sBGGrY2" }
From the code, when I add twice, the second time, I lose createdAt field.
I don't know why.????
I have got it !!!! Thank you very much for all comments
'upload': function upload(data, name, eventId) {
const wb = XLSX.read(data, {type:'binary'});
var checkUpdate;
XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]).forEach(r => {
if (!Registers.findOne({ firstname: r.firstname, lastname: r.lastname, eventid: eventId })) {
r.owner = this.userId,
r.username = Meteor.user().username,
r.updatedAt = new Date(),
r.amount = Number(r.amount),
r.eventid = eventId,
r.firstname = r.firstname.trim(),
r.lastname = r.lastname.trim(),
r.createdAt = new Date(),
Registers.insert(r)
} else {
r.owner = this.userId,
r.username = Meteor.user().username,
r.updatedAt = new Date(),
r.amount = Number(r.amount),
r.eventid = eventId,
r.firstname = r.firstname.trim(),
r.lastname = r.lastname.trim(),
Registers.update({ firstname: r.firstname, lastname: r.lastname, eventid: eventId }, { $set: {updatedAt: r.updatedAt, amount: r.amount } })
}
})
return wb;
},

I think you are looking for Collection.upsert method.
Basically it modifies one or more documents in the collection, or insert one if no matching documents were found. Returns an object with keys numberAffected (the number of documents modified) and insertedId (the unique _id of the document that was inserted, if any).

Related

Is there a way I can update mongodb document without a loop ie. with array as condition?

this is my document
{ "_id" : ObjectId("5ef05c35743df0112cbf5729"),
"doctor" : ObjectId("5e2ef5fd55e8c1043895aaf1"),
"patient" : ObjectId("5e0378d9a88e67364426be55"),
"requests" : [ { "_id" : ObjectId("5ef05c35743df0112cbf572d"),
"labTestType" : ObjectId("5ee752b9e26cbb3440b9259e"),
"result" : "",
"paymentstatus" : "Unpaid",
"createdAt" : ISODate("2020-06-22T07:22:29.664Z"),
"updatedAt" : ISODate("2020-06-22T07:22:29.664Z") },
{ "_id" : ObjectId("5ef05c35743df0112cbf572c"),
"labTestType" : ObjectId("5ee752b9e26cbb3440b925a6"),
"result" : "",
"paymentstatus" : "Unpaid",
"createdAt" : ISODate("2020-06-22T07:22:29.664Z"),
"updatedAt" : ISODate("2020-06-22T07:22:29.664Z") },
{ "_id" : ObjectId("5ef05c35743df0112cbf572b"),
"labTestType" : ObjectId("5ee752b9e26cbb3440b925b5"),
"result" : "",
"paymentstatus" : "Unpaid",
"createdAt" : ISODate("2020-06-22T07:22:29.664Z"),
"updatedAt" : ISODate("2020-06-22T07:22:29.664Z") },
{ "_id" : ObjectId("5ef05c35743df0112cbf572a"),
"labTestType" : ObjectId("5ee752b9e26cbb3440b925b6"),
"result" : "",
"paymentstatus" : "Unpaid",
"createdAt" : ISODate("2020-06-22T07:22:29.664Z"),
"updatedAt" : ISODate("2020-06-22T07:22:29.664Z") }
],
"createdAt" : ISODate("2020-06-22T07:22:29.664Z"),
"updatedAt" : ISODate("2020-06-23T06:35:06.420Z"), "__v" : 0 }
I want to update paymentstatus under requests to Paid by providing labTestType
Objectids as list of array.
Try this code this works for me
db.getCollection('your_collection').findOneAndUpdate(
{
$and: [
{ _id: new ObjectId(_id) }, //_id = "5ef05c35743df0112cbf5729"
{ 'requests.labTestType': { $in: [new ObjectId('5ee752b9e26cbb3440b9259e'), new ObjectId('5ee752b9e26cbb3440b925b5')] } }]
},
{
$set: { 'requests.$.paymentstatus': 'paid'
} //set new payment status
})
this worked for me i was missing $in property
db.getCollection('your_collection').updateMany(
{_id: newObjectId(_id)},
{$set: {"requests.$[element].paymentstatus": "Paid"}},
{ multi:true,
arrayFilters: [{ "element.labTestType": {$in: arraywithobjectIds}}]
})

Mongo attempts to create a field on update though I don't need this

I want to update a single field in all the embedded documents that match a query.
My update operation:
$set: { 'rows.baseValue': toValue }
However, I get an error of
Cannot create field 'baseValue' in element {rows: [ { baseName:
"Belts", baseAttr: "Detail", baseValue: "Knot", action: "delete",
customName: "", customAttr: "", customValue: "", _id:
ObjectId('5c692860843d26064d1f142a') }
mind that i do have baseValue field in this document, why it's trying to create another baseValue field and how to make it just update the existing value of existing baseValue field?
Document to modify:
{
"_id" : ObjectId("5c692860843d26064d1f1429"),
"updatedAt" : ISODate("2019-02-17T09:24:49.253Z"),
"createdAt" : ISODate("2019-02-17T09:24:49.253Z"),
"translationName" : "deleteLex",
"vertical" : "fashion",
"defaultAction" : "delete",
"rows" : [
{
"baseName" : "Belts",
"baseAttr" : "Detail",
"baseValue" : "Knot",
"action" : "delete",
"customName" : "",
"customAttr" : "",
"customValue" : "",
"_id" : ObjectId("5c692860843d26064d1f142a")
},
{
"baseName" : "Belts",
"baseAttr" : "Detail",
"baseValue" : "Pockets",
"action" : "delete",
"customName" : "",
"customAttr" : "",
"customValue" : "",
"_id" : ObjectId("5c692860843d26064d1f142b")
},
{
"baseName" : "Belts",
"baseAttr" : "Detail",
"baseValue" : "NewValue",
"action" : "delete",
"customName" : "",
"customAttr" : "",
"customValue" : "",
"_id" : ObjectId("5c692860843d26064d1f142c")
}]
}
To update all elements in an array you need the postional all operator $[], try:
db.col.update({ "_id" : ObjectId("5c692860843d26064d1f1429") }, { $set: { "rows.$[].baseValue": toValue } })
Otherwise $set will try to create new value on existing array which is not possible

How to query single document which contains specific value of some element in array of arrays MongoDB

I have an document that contains array of arrays i am using embedded document in MongoDb.Say i have collection name Orders looks like:-
"_id" : "HjPGrdkffg7dQPtiX",
"ListOrdersResult" : [
{
"Orders" : {
"Order" : [
{
"LatestShipDate" : "2016-01-13T18:29:59Z",
"OrderType" : "StandardOrder",
"PurchaseDate" : "2016-01-11T10:24:49Z",
"PaymentExecutionDetail" : {
"PaymentExecutionDetailItem" : {
"PaymentMethod" : "COD",
"Payment" : {
"CurrencyCode" : "INR",
"Amount" : "839.30"
}
}
},
"BuyerEmail" : "vccdbptpx2ssd74882#marketplace.amazon.in",
"AmazonOrderId" : "402-4031538-7451469",
"LastUpdateDate" : "2016-01-14T06:47:17Z",
"ShipServiceLevel" : "IN Exp Dom 2",
"NumberOfItemsShipped" : "1",
"OrderStatus" : "Shipped",
"SalesChannel" : "Amazon.in",
"ShippedByAmazonTFM" : "false",
"LatestDeliveryDate" : "2016-01-19T18:29:59Z",
"NumberOfItemsUnshipped" : "0",
"BuyerName" : "xyz",
"EarliestDeliveryDate" : "2016-01-13T18:30:00Z",
"OrderTotal" : {
"CurrencyCode" : "INR",
"Amount" : "839.30"
},
"IsPremiumOrder" : "false",
"EarliestShipDate" : "2016-01-11T18:30:00Z",
"MarketplaceId" : "A21TJRRWUN4KGVC",
"FulfillmentChannel" : "MFN",
"TFMShipmentStatus" : "Delivered",
"PaymentMethod" : "COD",
"ShippingAddress" : {
"StateOrRegion" : "HARYANA",
"City" : "GURGAON",
"Phone" : "9999999999",
"CountryCode" : "IN",
"PostalCode" : "122001",
"Name" : "Murthy",
"AddressLine1" : "House No. , J Block, Badshahpur"
},
"IsPrime" : "false",
"ShipmentServiceLevelCategory" : "Expedited"
},
{
"LatestShipDate" : "2016-01-13T18:29:59Z",
"OrderType" : "StandardOrder",
"PurchaseDate" : "2016-01-11T13:16:49Z",
"PaymentExecutionDetail" : {
"PaymentExecutionDetailItem" : {
"PaymentMethod" : "COD",
"Payment" : {
"CurrencyCode" : "INR",
"Amount" : "899.40"
}
}
},
"BuyerEmail" : "xyz#marketplace.amazon.in",
"AmazonOrderId" : "402-2142159-5087541",
"LastUpdateDate" : "2016-01-14T06:47:15Z",
"ShipServiceLevel" : "IN Exp Dom 2",
"NumberOfItemsShipped" : "1",
"OrderStatus" : "Cancel",
"SalesChannel" : "Amazon.in",
"ShippedByAmazonTFM" : "false",
"LatestDeliveryDate" : "2016-01-19T18:29:59Z",
"NumberOfItemsUnshipped" : "0",
"BuyerName" : "demo prakash",
"EarliestDeliveryDate" : "2016-01-13T18:30:00Z",
"OrderTotal" : {
"CurrencyCode" : "INR",
"Amount" : "899.40"
},
"IsPremiumOrder" : "false",
"EarliestShipDate" : "2016-01-11T18:30:00Z",
"MarketplaceId" : "A21TJEUUN4WGV",
"FulfillmentChannel" : "MFN",
"TFMShipmentStatus" : "Delivered",
"PaymentMethod" : "COD",
"ShippingAddress" : {
"StateOrRegion" : "DELHI",
"City" : "DELHI",
"Phone" : "99999999",
"CountryCode" : "IN",
"PostalCode" : "110038",
"Name" : "Demo prakash",
"AddressLine1" : "Hn 638 gali n 04 Wazirabad new delhi"
},
"IsPrime" : "false",
"ShipmentServiceLevelCategory" : "Expedited"
},
}
]
},
"CreatedBefore" : "2015-03-19T06:17:59Z"
}
],
"ResponseMetadata" : {
"RequestId" : "cf94645e-ada7-4ec6-b161-a97d07a77817"
},
"seller_user_id" : "yg4e34ccodzf3GPR2",
}
So as you can see this is the single document that contains the whole data of array i want to fetch the orders whose status is cancel from this order array.
So for that i have use :-
var orderDetails =
orders.find({"ListOrdersResult.Orders.Order":{$elemMatch:
{ OrderStatus:"Canceled"}}}).fetch();
Also i tried with:-
orders.find({"ListOrdersResult.Orders.Order.OrderStatus":'Canceled'}).fetch();
So this will return the whole document that contains status as canceled and other as well but i want only selected result from the document that contains status as pending.
So is there any way in mongoDb to query a selected value from a single document that contains nested array of arrays as object.
Or I need to staore the values into diff diff documents thats only the solution.
Any help would be appriciated please contribute
Thanks!
You can go with any meteor aggregate package. You can use match and then group the data then send it to client-side.Like :
var ordersLines = orders.aggregate([
{$unwind : "$ListOrdersResult.Orders.Order"},
{$match : { OrderStatus:"Canceled"} },
{$project : {
OrderType : '$ListOrdersResult.Orders.Order.OrderType'
....
}
}
]);
return ordersLines;
But I suggest you go with a different document.

MongoDB: Adding an array into an existing array

I'm trying to add an "Instructors" array into an already existing "Camps" array.
The hierarchical structure looks something like this:
owner = {
email : 'john.smith#gmail.com',
password : 'mypassword',
firstName : 'john',
lastName : 'smith',
camps : [
{
name : 'cubs-killeen',
location : 'killeen',
manager : {name: 'joe black', email: '', password: ''},
instructors : [
{
firstName : 'bill',
lastName : 'jones',
classes : []
},
{
firstName : 'jill',
lastName : 'jones',
classes : [],
},
],
students : []
}
]
};
I am using Node Express with MongoJS and have been able to successfully add an owner and add "camps", however, in the "addInstructor" function, when I try and add "Instructors" to a particular camp that is when the problems occur. I get no error message, instead it simply appends the "Instructors" array AFTER the items in the camps array.
Any help would be greatly appreciated. Below is my full code, with working functions and then the one that is not working and below that is my mongodb output (albeit wrong):
CampRepository = function(){};
CampRepository.prototype.addOwner = function(owner, callback){
console.log(db);
db.owners.save(owner, function(err, saved){
if (err || !saved) {
console.log('broke trying to add owner : ' + err);
callback(err);
} else {
console.log('save was successful');
callback(null, saved);
}
});
};
CampRepository.prototype.addCamp = function(ownerEmail, camp, callback){
db.owners.update(
{email: ownerEmail},
{$push: {
camps:{
name: camp.name,
location: camp.location,
managerName: camp.managerName,
managerEmail: camp.managerEmail,
managerPassword: camp.managerPassword,
managerPayRate: camp.managerPayRate,
instructors: [],
students: []
}
}
}, function(err, saved){
if (err || !saved) {
console.log('broke trying to add camp ' + err);
callback(err);
} else {
console.log('save was successful');
callback(null, saved);
}
});
};
/*
THIS IS THE ONE THAT DOESN'T WORK
*/
CampRepository.prototype.addInstructor = function(ownerEmail, campName, instructor, callback){
db.owners.update(
{email: ownerEmail, 'camps.name': campName},
{$push: {
camps:{
instructors: {
firstName: instructor.firstName,
lastName: instructor.lastName,
email: instructor.email
},
}
}
}, function(err, saved){
if (err || !saved) {
console.log('broke trying to add camp ' + err);
callback(err);
} else {
console.log('save was successful');
callback(null, saved);
}
});
};
OUTPUT
{
"_id" : ObjectId("51c7b04d2746ef6078000001"),
"email" : "john.smith#gmail.com",
"firstName" : john,
"lastName" : smith,
"password" : "mypassword",
"camps" : [
{
"name" : "cubs-killeen",
"location" : "killeen",
"managerName" : "bill jones",
"managerEmail" : "bill#gmail.com",
"managerPassword" : "secretpasscode",
"instructors" : [ ],
"students" : [ ]
},
{ "instructors" : { "name" : "jon tisdale" } }
]
}
You might need to take a look at this. you can achieve this using dot.notation
It's very powerfull way to find or update items in a larger array of document scheme. If you still not able to achieve this i would happy to provide you the following code...
I've inserted a new owner2
owner2 = {
email : 'murali.ramakrishnan#gmail.com',
password : 'mypassword',
firstName : 'murali',
lastName : 'ramakrishnan',
camps : [
{
name : 'Rotary club',
location : 'trichy',
manager : {name: 'baskaran', email: 'baskaran#mit.edu', password: 'baskaran'},
instructors : [
{
firstName : 'baskaran',
lastName : 'subbiah',
classes : []
},
{
firstName : 'david',
lastName : 'nover',
classes : [],
},
],
students : []
}
]};
If you see we just need to add a new instructor as requested...
let first add the document to the collection
db.try.insert(owner2);
here you go you have added a new document
now, i'm going to create a new instructor object to insert #newly created owner2
instructor1 = {
firstName : 'lakshmi',
lastName : 'kanthan',
classes : []
};
above is the document object for new instructor
you can perform this update in many ways, using mongodbs methods like
collection.update
collection.findAndModify
if you want to insert or update any value to the sub-document we need to find using a dot.notation and push the sub-document to the document, here the code
db.try.update(
{'camps.name': "Rotary club" },
{
$push: { 'camps.$.instructors' : instructor1 }
}
)
the above code inserts a new record under the instructor field as in the field an array it just pushes the sub-document
End-Result
{
"_id" : ObjectId("51c7b222c0468dc711a60916"),
"email" : "murali.ramakrishnan#gmail.com",
"password" : "mypassword",
"firstName" : "murali",
"lastName" : "ramakrishnan",
"camps" : [
{
"name" : "Rotary club",
"location" : "trichy",
"manager" : {"name": "baskaran", "email": "baskaran#mit.edu", "password": "baskaran"},
"instructors" : [
{
"firstName" : "baskaran",
"lastName" : "subbiah",
"classes" : []
},
{
"firstName" : "david",
"lastName" : "nover",
"classes" : [],
},
{
"firstName" : "lakshmi",
"lastName" : "kanthan",
"classes" : [],
}
],
"students" : []
}
]};

How to delete deep array in mongodb?

I am trying to delete "virtualNumber" : "12345" in the following document:
{
"_id" : ObjectId("50a9db5bdc7a04df06000005"),
"billingInfo" : null,
"date" : "dsfdsfsdfsd",
"description" : "sdfsdff",
"pbx" : {
"_id" : ObjectId("50a9db5bdc7a04df06000006"),
"did" : {
"1234567890" : {
"inventoryId" : "509df7547e84b25e18000001",
"didcountry" : "india",
"didState" : "bangalore",
"routeType" : "CallForward",
"didNumber" : "1234567890",
"didVirtualNumbers" : [
{
"virtualNumber" : "12345"
},
{
"virtualNumber" : "56789"
}
],
"id" : ObjectId("50a9db9acdfb4f9217000002")
}
},
},
I am using node.js, so I constructed a query in JavaScript:
var query = {_id: ObjectId("50a9db5bdc7a04df06000005")};
var obj = {};
obj["pbx.did.1234567890.didVirtualNumbers.virtualNumber"]=12345;
//problem
collection.update(query,{$pull:obj});
You need to match the array element like:
{"$pull": {"pbx.did.7259591220.didVirtualNumbers": {"virtualNumber": "12345"}}}
So you should change your code to:
obj["pbx.did.7259591220.didVirtualNumbers"]={"virtualNumber": "12345"};
Please refer to http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull
It mentions the pull field should be an array.

Categories