Mongoose找到多个匹配

时间:2015-05-04 08:54:13

标签: javascript node.js mongodb express mongoose

我是这项技术的新手,并使用使用Mongoose的Node和Express服务器。我有以下文档集的架构。



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




在这里,我得到一个位置名称列表,例如" NewYork"," London"," Paris" etc ...在请求中需要返回响应中的文档,如下所示....



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




从Node使用mongoose的最佳方式是什么?我认为对mongodb进行多次查询(每个查询都有一个位置)是一个坏主意。

有没有办法通过单次调用mongoose获得预期的json响应?感谢。

2 个答案:

答案 0 :(得分:2)

是的,使用 aggregation framework 获取所需的输出。聚合管道将由$group运算符管道阶段组成,该阶段按locName字段和$addToSet累加器运算符对文档进行分组,以添加orgNameempName字段到数组empList。最后一个管道阶段$project运算符然后使用新字段_id替换上一个聚合流中的locName字段。

为了演示这个概念,假设您有一个使用mongo shell插入的样本集合:

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
}

在Mongoose中,您可以像这样使用 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); 
});

答案 1 :(得分:1)

所有查询,当您需要按称为聚合的和值进行分组时。您可以在mongo docs中阅读相关内容,Mongoose中的相同方法有模型。要生成查询,可以使用以下代码:

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

});

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