遍历数组并运行Mongo查询以修改同一数组

时间:2019-05-15 01:06:41

标签: node.js mongodb promise bluebird

我有一个“用户”集合,其中包含类似文件

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

someId映射到另一个集合“工作”

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

我必须增强工作集合中用户集合中的数据

因此用户文档应为:

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

我有

    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;
    })

这似乎不起作用...知道我该怎么做吗?我知道我必须使用Promises / Async函数,但似乎找不到正确的组合。

3 个答案:

答案 0 :(得分:0)

只需使用mongo aggregate即可。它给您预期的结果。只需尝试

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"
            }
        }
    }
}
])

结果

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

答案 1 :(得分:0)

如果可以在mongodb聚合查询中进行操作,则根本不需要在javascript中进行操作。如下所示:

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"]
          }
        }
      }
    }
  }
])

答案 2 :(得分:0)

查看评论:

//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;
        }
    }
})