按其他集合中的数组索引对聚合数组进行排序(MongoDB)

时间:2019-07-02 05:39:01

标签: mongodb

条件

我有两个具有以下模式(简化)的集合。

第一个收藏

{
  elements: [
    { identifier: 'b' },
    { identifier: 'a' },
    { identifier: 'c' }
  ]
}

第二个收藏集

{
  index: 1,
  identifier: 'a',
  value: 5
}

目标

我想按索引汇总第二个,并确保identifier与第一个的顺序相同。

示例输出

[{
  index: 1,
  elements: [
    { identifier: 'b', value: 5 },
    { identifier: 'a', value: 3 },
    { identifier: 'c', value: 6 }
  ]
}, {
  index: 2,
  elements: [
    { identifier: 'b', value: 1 },
    { identifier: 'a', value: 2 },
    { identifier: 'c', value: 9 }
  ]
}, {
  index: 3,
  elements: [
    { identifier: 'b', value: 3 },
    { identifier: 'a', value: 6 },
    { identifier: 'c', value: 4 }
  ]
}]

请注意,identifier的顺序始终与第一个收藏夹相同。

我有什么

这就是我得到的:

[
  {
    "$group": {
      "_id": "$index",
      "elements": {
        "$push": {
          "value": "$value",
          "identifier": "$identifier"
        }
      }
    }
  },
  {
    "$project": {
      "_id": 0,
      "index": "$_id",
      "elements": 1
    }
  }
]

仅当按第1个集合identifier的顺序插入文档时,它才能给我正确的结果。但是不能保证插入顺序。

样本数据

第一个收藏

{
  elements: [
    { identifier: 'b' },
    { identifier: 'a' },
    { identifier: 'c' }
  ]
}

第二收藏

[{
  index: 1,
  identifier: 'a',
  value: 5
}, {
  index: 1,
  identifier: 'b',
  value: 3
}, {
  index: 1,
  identifier: 'c',
  value: 6
}, {
  index: 2,
  identifier: 'a',
  value: 1
}, {
  index: 2,
  identifier: 'b',
  value: 2
}, {
  index: 2,
  identifier: 'c',
  value: 9
}, {
  index: 3,
  identifier: 'a',
  value: 3
}, {
  index: 3,
  identifier: 'b',
  value: 6
}, {
  index: 3,
  identifier: 'c',
  value: 4
}]

1 个答案:

答案 0 :(得分:0)

使用1st collection的现有架构,我们将无法获得预期的结果,但是我们可以通过添加有助于我们进行自定义排序的属性来修改1st collection

添加了有助于我们对1st collection进行排序的新属性后,

{
  "_id": "5d1b72ab1031330010d8602c",
  "elements": [
    {
      "identifier": "b", "order": 1
    },
    {
      "identifier": "a",  "order": 2
    },
    {
      "identifier": "c",  "order": 3
    }
  ]
}

然后下面的查询将为我们带来所需的结果

db.2ndcollection.aggregate([
  { "$lookup" : { from : "1stcollection", localField: "identifier", foreignField:"elements.identifier", as:"newb" }},
  {$unwind: "$newb"},
  {$unwind: "$newb.elements"}, 
  {$project: { "identifier":1, "index":1, "value":1, 
               "newb.elements.identifier":1, "newb.elements.order":1, 
                flag : { $cond : { 
                        if : { $eq : [ "$identifier", "$newb.elements.identifier"] }, then : 1, else: 0 } }
              }
  },
  { $match: { flag : 1 } },
  { $sort : { "newb.elements.order" : 1} },
  { $group : {
      "_id": "$index", 
      "elements": { "$push": { "value": "$value", "identifier": "$identifier" } }
    }
  }
 ]);

用于实现结果的汇总管道阶段为

$lookup-合并两个集合

$unwind-展开阵列

$project-将所需的属性投影到下一阶段

$match-过滤出匹配项

$sort-对项目进行排序

$group-将项目分组