使用带 let 和管道的 $lookup 在 MongoDB 中声明变量

declaring variables in MongoDB using $lookup with let and pipeline

我正在尝试向我的站点添加喜欢 功能。我使用以下架构制作了一个 likes 集合。我正在使用自定义 _id 来避免创建额外的索引。

{
  _id: {
    postId: ObjectId,
    userId: ObjectId
  }
}

我的服务器上有一个路由,它使用 MongoDB 聚合 搜索 posts 集合。我正在尝试将 $lookup 阶段添加到当前管道,以便添加类型为 liked 属性 =23=]Boolean表示post是否被用户点赞。这是无法正常工作的 $lookup 阶段(liked returns 一直是一个空数组,即使有相应的 like 文档) :

{
  $lookup: {
    from: 'likes',
    let: { likedPostId: '$_id.postId', likerUserId: '$_id.userId' },
    pipeline: [
      { $match:
        { $expr:
          { $and:
            [
              { $eq: [
                '$$likerUserId',
                  ObjectId('12345')
              ]},
              { $eq: [
                  '$$likedPostId',
                  '$_id'
              ]}
            ]
          }
        }
      }
    }
  ],
  as: 'liked'
  }
}

我认为问题是 变量 实际上并没有保持我期望的值。有什么办法可以解决这个问题吗?另外,如果您知道更简单的实现方法,请与我分享,我将不胜感激。

我尝试比较两个相同的 ObjectId() 实例以确保 ObjectId 实例可以使用 $ 进行比较eq 运算符。还尝试在不同的 嵌套字段 上定义 嵌套变量 ,就像上面代码片段中的那些一样。这个问题中唯一不同的是我试图将属性拉到 _id 字段.

之外

P.S。我知道 liked 属性 将是 Array 而不是 Boolean。但我正在考虑在下一阶段将其转换为 Boolean。但这不是现在的问题。

恰恰相反。如果您 运行 $lookuplikes 集合上,那么 let 部分的目标是定义引用您在 运行 集合上的集合的变量。另一方面,您可以在 pipeline 中使用单个美元符号来引用 likes 集合中定义的字段。尝试:

{
    $lookup: {
        from: 'likes',
        let: { id: '$_id' },
        pipeline: [
            { $match:
                { $expr:
                { $and:
                    [
                    { $eq: [
                        '$_id.userId',
                        ObjectId('12345')
                    ]},
                    { $eq: [
                        '$_id.postId',
                        '$$id'
                    ]}
                    ]
                }
                }
            }
        ],
        as: 'liked'
    }
}

编辑:请查看 docs

let
Optional. Specifies variables to use in the pipeline field stages. Use the variable expressions to access the fields from the documents input to the $lookup stage.

The pipeline cannot directly access the input document fields. Instead, first define the variables for the input document fields, and then reference the variables in the stages in the pipeline.