【问题标题】:mongodb apply sort to lookup resultsmongodb 对查找结果应用排序
【发布时间】:2018-05-15 01:03:19
【问题描述】:

如果我有 userpost 集合

{"_id": 1, "name": "User 1"}
{"_id": 2, "name": "User 2"}

{"_id": 1, "title": "Post 1", "userId": 1, "createdAt": ISODate("2017-07-24T04:12:54.255Z")}
{"_id": 2, "title": "Post 2", "userId": 1, "createdAt": ISODate("2017-07-25T04:12:54.255Z")}
{"_id": 3, "title": "Post 1", "userId": 2, "createdAt": ISODate("2017-07-24T04:12:54.255Z")}

如何列出所有用户的最新帖子?会是这样的

{
  "_id": 1,
  "name": "User 1",
  "post": {
    "_id": 2,
    "title": "Post 2",
    "userId": 1,
    "createdAt": ISODate("2017-07-25T04:12:54.255Z")
  }
}

我知道我可以轻松使用 $lookup、$unwind post,然后按 post.createdAt 进行 $sort,但这给我留下了多余的用户(用户 1 将在帖子 1 和帖子 2 中列出两次)。

我不知道如何使用 $group 删除重复项,同时保持其他字段(名称、post.title 等)

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    我使用 $group 和 $first 解决了重复问题

    db.getCollection('user').aggregate([
        {$lookup: {from: "post", localField: "_id", foreignField: "userId", as: "post"}},
        {$unwind: { path: "$post", preserveNullAndEmptyArrays: true }},
        {$sort: {"post.createdAt": -1}},
        {$group: {"_id": "$_id", "name": {$first: "$name"}, "post": {$first: "$post"}},
        {$project: {"_id": 1, "name": 1, "post": 1}}
    ])
    

    欢迎发表你的答案

    【讨论】:

    • 当你不提供限制时它可以工作。考虑如果我提供 10 个帖子的限制,并且用户集合中的第一个用户有 12 个最近的帖子,那么????
    【解决方案2】:

    您可以使用新的$lookup 语法在单个聚合步骤中解决此问题

    db.getCollection('users').aggregate([{
        '$lookup': {
          'from': 'posts',
          'let': {
            'userId': '$_id'
          },
          'pipeline': [{
              '$match': { '$expr': { '$eq': ['$userId', '$$userId'] } }
            }, {
              '$sort': {  'createdAt': -1 }
            }, {
              '$limit': 10
            },
          ],
          'as': 'posts'
        }
      }
    ])
    

    注意:未经测试的代码,但原理应该清楚。

    【讨论】:

    • 完美运行,还展示了如何使用新的 $lookup 语法。 tnx 一百万!
    • 你不需要letpipeline,只需将$match、$sort、$limit放在$lookup之前(包括$localField、$foreignField),见docs.mongodb.com/manual/reference/operator/aggregation/lookup
    • 我不确定我理解你的意思,@netwire,你能分享一个例子吗?
    • 查找管道中的$sort 操作不会使用任何索引。所以这很可能会变得很慢。
    【解决方案3】:

    这是一种你可以使用的方法

    db.getCollection('post').aggregate([
    { $limit: 10 },
    
    {$sort: {"createdAt": -1}},
    
    {$lookup: {from: "user", localField: "userId", foreignField: "_id", as: "user"}},
    ])
    

    您应该查询按日期排序的帖子并加入用户。因此,如果您想为帖子提供限制,那么您可以。

    【讨论】:

      猜你喜欢
      • 2014-05-10
      • 1970-01-01
      • 2019-01-14
      • 2016-02-07
      • 1970-01-01
      • 2021-05-18
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      相关资源
      最近更新 更多