首页 > 解决方案 > 在 MongoDb 聚合查找中, let 是否需要特殊格式?

问题描述

我正在尝试将 MongoDB $lookup 与不相关的子查询一起使用。
使用 MongoDB 3.6.12(从 3.6 开始支持) https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/#join-conditions-and-uncorrelated-sub-queries

以下管道步骤正在运行,但是如果我将第一个“userB”换成第二个,则不会返回任何结果。

{
from: 'friendships',
let: { requestuser: ObjectId("5c0a9c37b2365a002367df79"), postuser: ObjectId("5c0820ea17a69b00231627be") },
pipeline: [
   { 
        $match : { 
            $or : [
                { 
                    "userA" : ObjectId("5c0820ea17a69b00231627be"), 
                    "userB" : ObjectId("5c0a9c37b2365a002367df79")
                     // "userB" : '$$requestuser'
                }, 
                { 
                    "userA" : ObjectId("5c0a9c37b2365a002367df79"), 
                    "userB" : ObjectId("5c0820ea17a69b00231627be")
                }
            ], 
            "accepted" : true
        }
    },
    {
   $project: {v: 'true'}
    }
 ],
as: "match"}

带有硬编码 ObjectId 的结果:

"match" : [
        {
            "_id" : ObjectId("5d6171dd319401001fd326bf"), 
            "v" : "true"
        }
    ]

使用变量的结果:

"match" : [

    ]

我觉得 ObjectIds 需要特殊处理。我能找到的所有示例都使用简单的变量,如字符串。

为了验证 '$$requestUser' 包含一个值,我在投影上对其进行了测试:

"match" : [
        {
            "_id" : ObjectId("5d6171dd319401001fd326bf"), 
            "v" : ObjectId("5c0a9c37b2365a002367df79")
        }
    ]

标签: mongodbmongodb-queryaggregation-frameworkmongodb-lookup

解决方案


当你使用不相关的子查询时,你需要使用$expr来传递一个变量。您可以尝试以下操作。

{
    $match: {
      $expr: {
        $or: [
            { 
                $and:[
                  {
                    $eq: [ "userA", ObjectId("5c0820ea17a69b00231627be") ]
                  },
                  {
                    $eq: [ "userB", ObjectId("5c0a9c37b2365a002367df79") ]
                  },
                  {
                    $eq: [ "userB", "$$requestuser" ]
                  }
                ]           
            },
            {
                $and:[
                  {
                    $eq: [ "userA", ObjectId("5c0a9c37b2365a002367df79") ]
                  },
                  {
                    $eq: [ "userB", ObjectId("5c0820ea17a69b00231627be") ]
                  }
                ]
            }
          
          
        ]
      },
      "accepted": true,
      
    }
  }

我创建了一个示例演示来展示$expr内部的工作原理lookup不相关子查询的示例演示


推荐阅读