3

I have a collection "user" with documents like

{
    _id:ObjectId("xx"),
    searches:[
        {someId:"yyy","fav_food":"pasta"},
        {someId: "zzz","fav_food":"macncheese"}
    ]
}

The someId maps to another collection "job"

{
_id:yyy,
job_name:"clerk",
"name": "kent"
},
{
_id:zzz,
job_name:"racer",
"name":"michael"
}

I have to enhance data in user collection from the job collection

So the user document should be:

{
    _id:ObjectId("xx"),
    searches:[
        {someId:"clerk::kent",fav_food:"pasta"},
        {someId: "michael::racer","fav_food":"macncheese"}
    ]
}

I have

    mongo_db.collection('job', function(err,coll){
        for(var i = 0; i <= data.searches.length-1; i++) {
            var pid = data.searches[i].someId;
            console.log("RELEASE ID " + someId);

            if(pid !== null || pid !== undefined){
                result =  coll.findOne({"_id":ObjectId(pid)});
                if(result){
                    console.log("this is data searches for index " + i+ " " + JSON.stringify(data.searches[i]) 
                            + " and data.searches " + JSON.stringify(data.searches) + " and this is result " + JSON.stringify(result));
                    data.searches[i].someId =  result.name + "::" + result.job_name;


                }
            }
        }
        return data;
    })

This does not seem to work... any Idea how I can do this? I know I have to use Promises/Async functions but I cannot seem to find the right combination.

5
  • This might help you stackoverflow.com/questions/51801033/… Commented May 15, 2019 at 3:05
  • No - i don't want to write it back to MongoDB. I would like to keep the result document and process it later. Do you know how I can use await/promises to solve my question? Commented May 15, 2019 at 4:19
  • you need to use await before coll.findOne({"_id":ObjectId(pid)}); Commented May 15, 2019 at 4:47
  • Its not required to do it in javascript when you can do it in mongodb aggregate query. see my answer below. Commented May 15, 2019 at 5:20
  • Possible duplicate of NodeJS callback after multiple async-functions in for-loop Commented May 17, 2019 at 3:45

3 Answers 3

0

Its not at all required to do it in javascript if you can do it in mongodb aggregate queries. Like this below:

db.user.aggregate([{
    $unwind: "$searches"
  },
  {
    $lookup: {
      from: "job",
      localField: "searches.someId",
      foreignField: "_id",
      as: "search"
    }
  },
  {
    $unwind: "$search"
  },
  {
    $group: {
      _id: "$_id",
      searches: {
        $addToSet: {
          "fav_food": "$searches.fav_food",
          "someId": {
            $concat: ["$search.name", '::', "$search.job_name"]
          }
        }
      }
    }
  }
])

Sign up to request clarification or add additional context in comments.

Comments

0

Check the comments:

//1. Below code snippet can optimize your task
//2. You will be able to return desire result

mongo_db.collection('job', function(err, coll) {
    var pid = [];
    for (var i = 0; i <= data.searches.length - 1; i++) {
        pid.push(data.searches[i].someId); //!! gather all the pids in array
        // console.log("RELEASE ID " + someId);
    }
    if (pid !== null || pid !== undefined) {
        // result = coll.findOne({ "_id": ObjectId(pid) });

        //!! Search all the data with $in agg. in one step
        //!! In this find all data's callback do your further task

        if (result) {
            //!! loop thru the result and make your desire array
            console.log("this is data searches for index " + i + " " + JSON.stringify(data.searches[i]) +
                " and data.searches " + JSON.stringify(data.searches) + " and this is result " + JSON.stringify(result));
            data.searches[i].someId = result.name + "::" + result.job_name;
            // !! retrun the data after loop
            return data;
        }
    }
})

Comments

0

Just do it with mongo aggregate. It gives your expected result. Just a try

db.getCollection('user').aggregate([
{
$unwind:{
    path:"$searches",
    preserveNullAndEmptyArrays:true
    }
},
{
$lookup:{
    from:"job",
    localField:"searches.someId",
    foreignField:"_id",
    as:"details"
    }
},
{
$unwind:{
    path:"$details",
    preserveNullAndEmptyArrays:true
    }
},
{
$group:{
    _id:"$_id",
    searches:{
        $push:{
            someId:{ $concat: [ "$details.job_name", "::", "$details.name" ] },
            fav_food:"$searches.fav_food"
            }
        }
    }
}
])

Result

{
"_id" : ObjectId("5cdb9dce6b57e490aaee734a"),
"searches" : [ 
    {
        "someId" : "clerk::kent",
        "fav_food" : "pasta"
    }, 
    {
        "someId" : "racer::michael",
        "fav_food" : "macncheese"
    }
]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.