2013-05-16 38 views
1

我有一份员工名单,每名员工属于一个部门和一家公司。可能使用聚合框架使用slice操作符?

员工还有薪水历史。最后一个值是他们目前的薪水。

例子:

{ 
    name: "Programmer 1" 
    employee_id: 1, 
    dept_id: 1, 
    company_id: 1, 
    salary: [50000,50100,50200] 
}, 
{ 
    name: "Programmer 2" 
    employee_id: 2, 
    dept_id: 1, 
    company_id: 1, 
    salary: [50000,50200,50300] 
}, 
{ 
    name: "Manager" 
    employee_id: 3, 
    dept_id: 2, 
    company_id: 1, 
    salary: [60000,60500,61000] 
}, 
{ 
    name: "Contractor (different company)" 
    employee_id: 4, 
    dept_id: 1, 
    company_id: 2, 
    salary: [60000,60500,75000] 
} 

我想找到员工目前的平均工资,由dept_id为和的company_id分组。

是这样的:

db.employees.aggregate(
    { $project : { employee_id: 1, dept_id: 1, company_id: 1, salaries: 1}}, 
    { $unwind : "$salaries" }, 
    { 
    "$group" : { 
     "_id" : { 
      "dept_id" : "$dept_id", 
      "company_id" : "$company_id", 
     }, 
     current_salary_avg : { $avg : "$salaries.last()" } 
    } 
    } 
); 

在这种情况下这将是

公司1,第1组:50250

公司1,组2:61000

公司2,组1:75000

我见过一些类似于$ unwind的例子,但我正在努力获得薪水的最后价值。在这种情况下,$ slice是否是正确的操作符,如果是这样的话,我如何在项目中使用它?

+0

没有排序,你可以得到最后的东西,你需要一种即使片,让你觉得你会得到 – Sammaye

回答

2

在这种情况下,你需要设置你的管道如下:

  1. 放松身心的工资表把所有的工资为每个员工
  2. 组由员工,部门和企业,并获得最后的薪水
  3. 组由部门和公司,并获得平均工资

此聚集管道的代码是:

use test; 

db.employees.aggregate([ 
    {$unwind : "$salary"}, 
    { 
     "$group" : { 
      "_id" : { 
       "dept_id" : "$dept_id", 
       "company_id" : "$company_id", 
       "employee_id" : "$employee_id", 
      }, 
      "salary" : {$last: "$salary"} 
     } 
    }, 
    { 
     "$group" : { 
      "_id" : { 
       "company_id" : "$_id.company_id", 
       "dept_id" : "$_id.dept_id", 
      }, 
      "current_salary_avg" : {$avg: "$salary"} 
     } 
    }, 
    {$sort : 
    { 
     "_id.company_id" : 1, 
     "_id.dept_id" : 1, 
    } 
    }, 

]); 

假设您已经导入的数据有:

mongoimport --drop -d test -c employees <<EOF 
{ name: "Programmer 1",     employee_id: 1, dept_id: 1, company_id: 1, salary: [50000,50100,50200]} 
{ name: "Programmer 2",     employee_id: 2, dept_id: 1, company_id: 1, salary: [50000,50200,50300]} 
{ name: "Manager",       employee_id: 3, dept_id: 2, company_id: 1, salary: [60000,60500,61000]} 
{ name: "Contractor (different company)", employee_id: 4, dept_id: 1, company_id: 2, salary: [60000,60500,75000]} 
EOF 
+0

完美的最后一个值。步骤2分组是我错过的。非常感谢。 –

+0

不客气。尽管如果您将数据更改为具有单个薪水标量和salary_history数组,可能会更简单。 – jimoleary

0

现在你可以使用$slice in aggregation。要从数组的开头或结尾返回元素:{ $slice: [ <array>, <n> ] } 要从数组中的指定位置返回元素:{ $slice: [ <array>, <position>, <n> ] }

和一对夫妇从蒙戈页面的例子:

{ $slice: [ [ 1, 2, 3 ], 1, 1 ] } // [ 2 ] 
{ $slice: [ [ 1, 2, 3 ], -2 ] }  // [ 2, 3 ] 
{ $slice: [ [ 1, 2, 3 ], 15, 2 ] } // [ ] 
{ $slice: [ [ 1, 2, 3 ], -15, 2 ] } // [ 1, 2 ]