如何减少聚合管道中的重复数据?

时间:2020-06-02 00:25:38

标签: mongodb pipeline projection

我的管道可以很好地满足我的需求...但是我认为可以从管道中删除一些冗余数据。

预期产量

这就是我希望输出看起来像

{
  "_id": "5ecee2189fdd1b0004056936",
  "name": "Mike",
  "history": [
    {
        "_id": "5ecb263c166b8500047c1411",
        "what": "Log IN"
    },
    {
        "_id": "5ecb263c166b8500047c1422",
        "what": "Log OUT"
    }
  ]
}

电流输出

这是当前输出的样子

{
  "docs": [
    {
      "_id": "5ecee2189fdd1b0004056936",
      "name": "Mike",
      "history": {
        "_id": "5ecb263c166b8500047c1411",
        "what": "Log IN"
      },
      "historyIndex": 0
    },
    {
      "_id": "5ecee2189fdd1b0004056936",
      "name": "Mike",
      "history": {
        "_id": "5ecb263c166b8500047c1422",
        "what": "Log OUT"
      },
      "historyIndex": 1
    }
  ]
}

用户文档

在现实生活中,会有更多的用户……当然...

{
  "_id": "5ecee2189fdd1b0004056936",
  "name": "Mike",
}

历史记录文档

再次,为了简单起见,我保持数据简短

[
  {
    "_id": "5ecb263c166b8500047c1411",
    "userId": "5ecee2189fdd1b0004056936",
    "what": "Log IN"
  },
  {
    "_id": "5ecb263c166b8500047c1422",
    "userId": "5ecee2189fdd1b0004056999",
    "what": "Log IN"
  },
  {
    "_id": "5ecb263c166b8500047c1433",
    "userId": "5ecee2189fdd1b0004056936",
    "what": "Log OUT"
  },
  {
    "_id": "5ecb263c166b8500047c1444",
    "userId": "5ecee2189fdd1b0004056999",
    "what": "Log OUT"
  }
]

mongoose-aggregate-paginate-v2中间件

我也在使用mongoose-aggregate-paginate-v2,但是我不认为这是我的问题,但是当返回结果时它肯定会起作用。它需要将文档弄平,以便可以计数和分页:

    "totalDocs": 941,
    "limit": 500,
    "page": 1,
    "totalPages": 2,
    "pagingCounter": 1,
    "hasPrevPage": false,
    "hasNextPage": true,
    "prevPage": null,
    "nextPage": 2

管道

这是我的管道

        var agg_match = {
            $match: 
            {
                _id: mongoose.Types.ObjectId(userId)
            }
        };

        var agg_lookup = {
            $lookup: {
                from: 'it_userhistories',
                localField: '_id',
                foreignField: 'userId',
                as: 'history'
            }
        }

        var agg_unwind = {
            $unwind: {
                path: "$history",
                preserveNullAndEmptyArrays: true,
                includeArrayIndex: 'historyIndex',
            }
        }

        var agg = [
            agg_match,
            agg_lookup,
            agg_unwind,
            agg_project,
        ];


        var pageAndLimit = {
            page:page,
            limit:limit
        }


       User.aggregatePaginate(myAggregate, pageAndLimit)

1 个答案:

答案 0 :(得分:1)

您可以使用$map运算符来执行此操作。以下查询会有所帮助(我尚未在管道中包含“比赛”阶段,您可以轻松地将其包括在内):

db.user.aggregate([
  {
    $lookup: {
      from: "history",
      localField: "_id",
      foreignField: "userId",
      as: "history"
    }
  },
  {
    $project: {
      name: 1,
      history: {
        $map: {
          input: "$history",
          as: "h",
          in: {
            _id: "$$h._id",
            what: "$$h.what"
          }
        }
      }
    }
  }
])

MongoPLayGroundLink