查看对象的嵌套数组是否包含值 | MongoDB

问题描述 投票:0回答:1

我有一个集合

posts
,其中有一个对象数组
comments
。在这个对象数组中,我有另一个对象数组
likes

我正在尝试编写一个查询,从帖子中提取最近 5 条评论,并且根据用户是否已经喜欢该评论,仅提取

true
false
likes

到目前为止我已经写了:

db.posts.aggregate([
    {
        "$match": {
            "_id": postId
        }
    },
    {
        "$project": 
        {
            "comments": {
                "$slice": [ "$comments", -5 ]
            }
        }
    },
    {
        "$project": {
            "comments.content": 1,
            "comments.likes": { 
                "$eq":  [ "comments.likes.$.createdBy.username", username ] 
            } 
        }
    }
])

但这似乎每次都会拉

false

是否可以做到这一点而无需编写单独的查询来检查用户是否喜欢?

编辑:对于以下文档:

username = "testusername"
postId = "60fcd335abbe5a73583b69f0"

我期望输出:

[
    {
        "content": "test comment",
        "likes": true
    },
    {
        "content": "another test comment",
        "likes": true
    }
]

username = "testusername2"
我期望输出

[
    {
        "content": "test comment",
        "likes": true
    },
    {
        "content": "another test comment",
        "likes": false
    }
]

回答

感谢@ray 在这方面的帮助。 这里是压缩代码,请参阅 ray 对代码拆分的响应以及解释。

mongodb mongoose mongodb-query aggregation-framework
1个回答
1
投票

您可以使用

$map
逐层处理数组。

  1. 您可以先
    $map
    评论来投射一个布尔值,表示用户1是否喜欢这些赞
  2. 然后您可以使用
    $anyElementTrue
    对投影布尔值进行检查
db.posts.aggregate([
  {
    "$match": {
      "_id": "p1"
    }
  },
  {
    "$project": {
      "comments": {
        "$slice": [
          "$comments",
          -5
        ]
      }
    }
  },
  {
    "$project": {
      likes: {
        "$map": {
          "input": "$comments",
          "as": "c",
          "in": {
            content: "$$c.content",
            likedByU1: {
              "$map": {
                "input": "$$c.likes",
                "as": "l",
                "in": {
                  $eq: [
                    "$$l.createdBy._id",
                    "u1"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    "$project": {
      likes: {
        "$map": {
          "input": "$likes",
          "as": "l",
          "in": {
            content: "$$l.content",
            likedByU1: {
              "$anyElementTrue": [
                "$$l.likedByU1"
              ]
            }
          }
        }
      }
    }
  }
])

这里是 Mongo Playground 来展示这个想法(对你的示例进行一些小的修改)。您可以修改它以满足您的需要。

© www.soinside.com 2019 - 2024. All rights reserved.