具有多个字段的组,但将字段视为相等

时间:2015-12-06 19:45:55

标签: mongodb aggregation-framework

假设我有两个城市之间的旅行信息数据。例如,

{ from: 'Paris', to: 'New York' }
{ from: 'New York', to: 'Paris' },
{ from: 'London', to: 'Moscow' },
{ from: 'Paris', to: 'New York' }
// etc...

我想计算某些城市之间的旅行次数。诀窍是从伦敦到莫斯科的旅行应该被视为从莫斯科到伦敦的旅行,即旅行的方向无关紧要。 如何使用mongodb聚合框架实现这一目标?

两个字段的简单分组不会忽略方向

db.trips.aggregate([
  {$group: { _id: { from: "$from", to: "$to" }, count: { $sum: 1} } }
])

并将导致以下结果

{ _id: {from: 'New York', to: 'Paris'}, count: 1 },
{ _id: {from: 'London', to: 'Moscom'}, count: 1 },
{ _id: {from: 'Paris', to: 'New York'}, count: 2 }
// etc...

但是我希望它说明巴黎和纽约之间的旅行已经进行了3次。

P.S。这篇文章的标题可能并没有很好地描述我想要达到的目标,但不幸的是我当时想不到更好的。因此,请随意修改。

1 个答案:

答案 0 :(得分:1)

非常有趣的问题。我找到了一种方法,有点棘手,但它正在做这项工作。

快速回答:

db.travels.aggregate([
    {
        $project:
        {
            city1:
            {
                $cond: { if: { $gte: [ "$from", "$to" ] }, then: "$to", else: "$from" }
            },
            city2:
            {
                $cond: { if: { $lt: [ "$from", "$to" ] }, then: "$to", else: "$from" }
            }
        }
    }
    ,{
        $group: 
        { 
            _id: 
            { 
                from: "$city1",
                to: "$city2"
            }
            ,count: { $sum: 1}
        }
    }
])

<强>阐释:

首先,使用$ project我使用$cond按字母顺序排序$from$tocity1(新$ from)始终是按字母顺序排列的“最小”字母的城市。 city2始终是“最大的”。

然后,在$project的末尾,我有你需要的东西,我使用你的$group(顺便说一句,你的代码中有一个拼写错误,count应该是在括号之前)。

<强>结果:

{
  "result": [
    {
      "_id": {
        "from": "London",
        "to": "Moscow"
      },
      "count": 1
    },
    {
      "_id": {
        "from": "New York",
        "to": "Paris"
      },
      "count": 3
    }
  ],
  "ok": 1
}