MongoDB Pipeline $lookup仅在硬编码对象id时有效

9wbgstp7  于 2023-11-17  发布在  Go
关注(0)|答案(1)|浏览(148)

我在MongoDB聚合管道阶段遇到了一个奇怪的问题。
以下是前一阶段的结果:

[
  {
    "_id": {
      "$oid": "6532b629454826446d8f399c"
    },
    "title": "Learning"
  }
  // ... more objects
]

字符串
当我定义下一个$match阶段时,如下所示(使用硬编码的ObjectID):

{
  from: "characterengagements",
  let: {
    tagId: { $toObjectId: '$$ROOT._id' },
  },
  pipeline: [
    { $match: { tags: ObjectId("6532b629454826446d8f399c") } },
    { $addFields: { testTagId: '$$tagId' } }
  ],
  as: "topCharacters"
}


我从pipeline得到以下输出:
请注意:

  • 这个文档被正确地返回,因为tags数组字段包含上面指定的对象id。
  • testTagId显示正确的值(与我硬编码的值相同)
[
  {
    "_id": {
      "$oid": "6532b629454826446d8f399c"
    },
    "title": "Learning",
    "topCharacters": [
      {
        "_id": {
          "$oid": "6532d773454826446dd2b967"
        },
        "character": {
          "$oid": "6532b63aacd66daa12860580"
        },
        "createdAt": {
          "$date": "2023-10-20T19:39:31.517Z"
        },
        "tags": [
          {
            "$oid": "6531c7d2fe4908d7ec87a58a"
          },
          {
            "$oid": "6532b5e6454826446d8ed08c"
          },
          {
            "$oid": "6532b629454826446d8f399c"
          },
          {
            "$oid": "6532b62c454826446d8f3de7"
          },
          {
            "$oid": "6532b74a454826446d91056b"
          }
        ],
        "testTagId": {
          "$oid": "6532b629454826446d8f399c"
        }
      }
    ]
  },
  // ... more documents
]


当我没有硬编码这个值,而是尝试使用$$tagId(如上所示,它被正确格式化)时,问题就出现了:

{
  from: "characterengagements",
  let: {
    tagId: { $toObjectId: '$$ROOT._id' },
  },
  pipeline: [
    { 
      $match: {
        // $$tagId should be the same as the hard coded value above, as shown by adding testTagId to the output from above, however, I get different results.
        tags: '$$tagId'
      } 
    },
    { 
      $addFields: {
        tagIdWas: '$$tagId'
            }
      
    }
  ],
  as: "topCharacters"
}


以上不返回任何文档。
如果有人遇到这个问题之前,我会非常感谢你的帮助。
谢谢你,谢谢

tf7tbtn2

tf7tbtn21#

在文档中,您必须使用$expr运算符来访问$match阶段中的变量。

{
  from: "characterengagements",
  let: {
    tagId: { $toObjectId: '$$ROOT._id' },
  },
  pipeline: [
    { 
      $match: {
        $expr: {
          $in: [
            "$$tagId",
            "$tags"
          ]
        }
      }
    },
    { 
      $addFields: {
        tagIdWas: '$$tagId'
      }
    }
  ],
  as: "topCharacters"
}

字符串
旁注,我认为转换为ObjectId似乎没有必要,因为_idObjectId。您可以简化为:

let: { tagId: "$_id" }


如果您使用MongoDB 5.0或更高版本,则可以同时使用localFieldforeignField

{
  from: "characterengagements",
  localField: "_id",
  foreignField: "tags",
  let: { tagId: "$_id" }
  pipeline: [
    { 
      $addFields: {
        tagIdWas: '$$tagId'
      }
    }
  ],
  as: "topCharacters"
}

相关问题