I'm working on a batch process that reads info from several sources, does some kind of transformation and finally writes output to a file in a per record basis (csv). In the mean time it also does insertions in a Mongo db. Its constructed with nodejs and uses mongodb node driver. The thing is that the schema is created on the fly (at least in the first run) although the total number of documents is fixed in every run and determined quite at the begining of the run. In one of the stages I need to create an array field with this structure:
{"notImpacted": [
{"IMPACTO": "IMPACT1",
"requests": [ {"name": "request11"},{"name":"request12"}]},
{"IMPACTO": "IMPACT2",
"requests": [ {"name": "request21"},{"name":"request22"}]}
]}
The idea is to create this field in sucessive calls to an function whose main logic is to look for the existence of the notImpacted.IMPACTO field for an specific _id. If it doesn't exist it creates the record via $push. If exists it does an $addToSet to notImpacted.$.requests as follows:
.
.
.
var notImp = {};
notImp.IMPACTO = request.PRODUCT;
notImp.requests = [];
notImp.requests.push(request); //request -> function call parameter
var cursor = col.find({"_id": codigo, "notImpacted.IMPACTO": request.PRODUCT_ID});
cursor.toArray().then(function(docs){
if(docs.length == 0){
return col.updateOne(
{"_id": codigo},
{$push: {"notImpacted": notImp}};
}
else
{
return col.updateOne(
{"_id": codigo, "notImpacted.IMPACTO": request.PRODUCT_ID},
{$addToSet: {"notImpacted.$.requests": request}}); /
}
})
.then(function(r){
.
.
The thing is that the first time I run the batch with an empty collection I get this kind of result (assuming just one impact with two requests)
{"notImpacted": [
{"IMPACTO": "IMPACT1",
"requests": [ {"name": "request11"}]},
{"IMPACTO": "IMPACT1",
"requests": [ {"name": "request12"}]}
]}
when I should get (both requests under same impact:
{"notImpacted": [
{"IMPACTO": "IMPACT1",
"requests": [ {"name": "request11"}, {"name": "request12"}]}
]}
Debugging shows the process keeps entering the first condition in the if clause(no documents found so it creates the array field notImpacted)
Curiously, if I run again the process, without dropping the db, in the second(and following) passes the results are:
{"notImpacted": [
{"IMPACTO": "IMPACT1",
"requests": [ {"name": "request11"}, {"name": "request12"}]},
{"IMPACTO": "IMPACT1",
"requests": [ {"name": "request12"}]}
]}
So it now detects the existence of the IMPACTO:IMPACT1 and does the $addToSet, the other field remains there.
I have the same functionality somewhere else in the program with some other fields and works as expected. I thing this might been some kind of race conditions so no matter what, when I do the first update the subsequent read does not get it and acts as if the find doesn't get anything. Aftewards, in subsequent runs the find succeeds and everything works fine. I would appreciate some advice to handle this situation. Wether by using some of the update options w:,j, etc. or if this is an unavoidable and expected behaviour some recomendation to handle this kind of situations. Thanks for your time
via E. G. M. G.
No comments:
Post a Comment