【问题标题】:How to use $in in array of embed array mongodb如何在嵌入数组mongodb的数组中使用$in
【发布时间】:2019-09-21 10:56:14
【问题描述】:

我有 photos_cmets 收藏:

{
    "_id" : ObjectId(""),
    "photo_id" : ObjectId(""),
    "content" : "Comment 1",
    "is_approved" : "1",
    "user" : {
        "user_id" : ObjectId(""),
        "name" : "",
        "avatar" : ".jpg"
    },
    "likes" : [ 
        {
            "user_id" : ObjectId("")
        }
    ],
    "like_count" : 1,
    "reply_count" : 5,
    "replies" : [ 
        {
            "reply_id" : ObjectId(""),
            "content" : "Reply 1",
            "is_approved" : "1",
            "user" : {
                "user_id" : ObjectId(""),
                "name" : "",
                "avatar" : ".jpg"
            },
            "likes" : [ 
                {
                    "user_id" : ObjectId("")
                }
            ],
            "like_count" : 1
        }, 
    ]
}

我使用 $in 检查当前用户是否喜欢回复评论:

$collection->aggregate(
                        [
                            [
                                '$match' => [
                                    '_id' => new ObjectId($comment_id)
                                ]
                            ],

                            [
                                '$project' => [
                                    'replies.reply_id' => 1,
                                    'replies.like_count' => 1,
                                    'replies.content' => 1,
                                    'replies.is_liked' => ['$in' => [['user_id' => $user_id], '$replies.likes']],
                                    'replies.user' => 1,
                                    'replies.created_at' => 1
                                ]
                            ],

                            ['$sort' => ["replies.reply_id" => 1]],
                            ['$limit' => 5]
                        ]);

但是replies.is_liked 总是返回false,尽管它存在于replies 数组嵌入的likes 数组中的user_id。

如何解决?谢谢!

看起来您的帖子主要是代码;请添加更多详细信息。

【问题讨论】:

  • 您实际期望的结果是什么? 显示您的预期结果。请注意,您的文档中的replies 如图所示是一个数组,因此$project 阶段中​​的简单“点符号”不足以更改 每个数组元素。如果您希望所有数组元素都被更改,那么您必须使用$map

标签: php mongodb mongodb-query


【解决方案1】:

如果您想根据条件更改数组内容以添加新字段,那么您需要$map 运算符,如果您不想限制或更改其余部分,则可能使用$addFields返回文件:

$collection->aggregate([
  [ '$match' => [
    '_id' => new ObjectId($comment_id)
  ]],
  [ '$addFields' => [
    'replies' => [
      '$map' => [
        'input' => '$replies',
        'in' => [
          'reply_id' => '$$this.reply_id',
          'content' => '$$this.content',
          'is_approved' => '$$this.is_approved',
          'is_liked' => [ '$in' => [ $user_id, '$$this.likes.user_id' ] ],
          'like_count' => '$$this.like_count'
        ]
      ]
    ]
  ]],
  ... # any other pipeline
])

如果您的 MongoDB 支持并且您更喜欢,请使用 $mergeObjects

$collection->aggregate([
  [ '$match' => [
    '_id' => new ObjectId($comment_id)
  ]],
  [ '$addFields' => [
    'replies' => [
      '$map' => [
        'input' => '$replies',
        'in' => [
          '$mergeObjects' => [
            '$$this',
            [ 'is_liked' => [ '$in' => [ $user_id, '$$this.likes.user_id'  ] ] ]
          ]
        ]        
      ]
    ]
  ]],
  ... # any other pipeline
])

当然,在这两种情况下,$user_id 是您的 PHP 变量,作为 $in 的参数中的 singular 值,'$$this.likes.user_id' 是 @987654334 数组的 MongoDB 表示@ 内部数组中的值。注意 arraysecond 参数,而 singularfirst

$map 运算符使用'$$this' 来表示正在处理的数组的当前元素。在这两个示例中,这都允许数组内容的重新映射,正如运算符名称所暗示的那样。

【讨论】:

  • 感谢您的详细说明。它给出了正确的结果。很抱歉反馈迟了。
猜你喜欢
  • 2018-03-11
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
  • 2016-10-26
  • 2022-01-17
  • 2018-05-09
相关资源
最近更新 更多