2015-05-04 72 views
3

我是新来这种技术,并与使用猫鼬的Node和Express服务器一起工作。我有一个文档集合的以下架构。猫鼬找到多个匹配

var empSchema = new mongoose.Schema({ 
 
\t _id: String, 
 
\t orgName: {type: String, required: true}, 
 
\t locName: {type: String, required: true}, 
 
\t empName: {type: String, required: true} 
 
});

在这里,我得到“纽约”位置的名单,“伦敦”,“巴黎”等......在请求中,需要在响应为返回的文件下面....

{ 
 
result:[{locName:"NewYork", 
 
\t empList:[ 
 
\t \t {orgName:"abc", empName:"emp1"}, 
 
\t \t {orgName:"xyz", empName:"emp2"}] 
 
\t }, 
 
\t {locName:"London", 
 
\t empList:[ 
 
\t \t {orgName:"pkq", empName:"emp13"}, 
 
\t \t {orgName:"mns", empName:"emp23"}] 
 
\t }] 
 
}

什么是使用从猫鼬的最佳方式节点。我认为对MongoDB进行多个查询(每个都有一个位置)是一个坏主意。

有没有一种方法可以通过单个调用mongoose来获得预期的json响应?谢谢。

回答

2

是的,使用aggregation framework来获得所需的输出。聚合流水线将包括一个$group操作员流水线阶段,该阶段通过locName字段和$addToSet累加器操作符将文档分组,以将orgNameempName字段添加到数组empList。最后的流水线阶段$project运营商随后用新字段locName替换来自先前汇聚流的_id字段。

为了证明这一概念,假设有你与蒙戈壳插入样品收集:

db.employees.insert([ 
    { 
     _id: "1", 
     orgName: "abc", 
     locName: "New York", 
     empName: "emp1" 
    }, 
    { 
     _id: "2", 
     orgName: "xyz", 
     locName: "New York", 
     empName: "emp2" 
    }, 
    { 
     _id: "3", 
     orgName: "pkq", 
     locName: "London", 
     empName: "emp13" 
    }, 
    { 
     _id: "4", 
     orgName: "mns", 
     locName: "London", 
     empName: "emp23" 
    } 
]) 

下聚合产生所期望的结果:

db.employees.aggregate([ 
    { 
     "$group": { 
      "_id": "$locName", 
      "empList": { 
       "$addToSet": { 
        "orgName": "$orgName", 
        "empName": "$empName" 
       } 
      } 
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, 
      "locName": "$_id", 
      "empList": 1 
     } 
    } 
]) 

输出

/* 0 */ 
{ 
    "result" : [ 
     { 
      "empList" : [ 
       { 
        "orgName" : "mns", 
        "empName" : "emp23" 
       }, 
       { 
        "orgName" : "pkq", 
        "empName" : "emp13" 
       } 
      ], 
      "locName" : "London" 
     }, 
     { 
      "empList" : [ 
       { 
        "orgName" : "xyz", 
        "empName" : "emp2" 
       }, 
       { 
        "orgName" : "abc", 
        "empName" : "emp1" 
       } 
      ], 
      "locName" : "New York" 
     } 
    ], 
    "ok" : 1 
} 

In猫鼬,您可以使用aggregation pipeline建设者这样的:

Employee.aggregate() 
     .group({ 
      "_id": "$locName", 
      "empList": { 
       "$addToSet": { 
        "orgName": "$orgName", 
        "empName": "$empName" 
       } 
      } 
     }) 
     .project({ 
      "_id": 0, 
      "locName": "$_id", 
      "empList": 1 
     }) 
     .exec(function (err, res) { 
      if (err) return handleError(err); 
      console.log(res); 
    }); 

// Or the simple aggregate method 
var pipeline = [ 
    { 
     "$group": { 
      "_id": "$locName", 
      "empList": { 
       "$addToSet": { 
        "orgName": "$orgName", 
        "empName": "$empName" 
       } 
      } 
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, 
      "locName": "$_id", 
      "empList": 1 
     } 
    } 
] 

Employee.aggregate(pipeline, function (err, res) { 
    if (err) return handleError(err); 
    console.log(res); 
}); 
+3

非常好,清晰详细的一个。你做了我的一天,非常感谢。 – harik

+1

@harik不用担心:-) – chridam

1

所有查询,当您需要通过称为聚合的总和值进行分组时。你可以在mongo docs中看到它,同样的方法在Mongoose有模型。要生成查询,你可以使用这样的代码:

Employee 
    .aggregate() 
    .group({ _id: '$locName', empList: { $push: "$$ROOT" }}) 
    .exec(function (err, res) { 

}); 

如果您不需要查询所有表,还有有一个match方法。

+0

谢谢,这是有益的。 – harik