MongoDB ObjectId 与 String 的关联

1,998 阅读1分钟
  • 场景:

    现有两个集合如下:

    company: {_id: ObjectId("..."), countryId: "566eb3c704c7b31facbb0007"}
    country: { _id: ObjectId("566eb3c704c7b31facbb0007"), name:"..."} 
    

    正常关联:

    { $lookup: {
           from: "country",
           localField: "countryId",    <= string
           foreignField: "_id",    <= ObjectId
           as: "country"
    }}
    

    但结果却是无效

  • 解决方案:

    1. 使用 $project

      db.company.aggregate([
        {
          "$project": {
            "countryId": {
              "$toObjectId": "$countryId"
            }
          }
        },
        {
          "$lookup": {
            "from": "country",
            "localField": "countryId",
            "foreignField": "_id",
            "as": "country"
          }
        }
      ])
      

      或:

      db.company.aggregate([
        {
          "$project": {
            "_id": {
              "$toString": "$_id"
            }
          }
        },
        {
          "$lookup": {
            "from": "country",
            "localField": "countryId",
            "foreignField": "_id",
            "as": "country"
          }
        }
      ])
      
    2. 使用 $lookuplet 属性

      db.company.aggregate([
        { 
            "$lookup": {
                "let": { "countryId": { "$toObjectId": "$countryId" } },
                "from": "country",
                "pipeline": [
                  { "$match": { "$expr": { "$eq": [ "$_id", "?countryId" ] } } }
                 ],
                "as": "country"
          }
        }
      ])
      
    3. 使用 $addFields

      db.role.aggregate([
        { "$addFields": { "countryId": { "$toObjectId": "$countryId" }}},
        { "$lookup": {
          "from": "country",
          "localField": "countryId",
          "foreignField": "_id",
          "as": "country"
        }}
      ])