首页 > 解决方案 > 查找文档及其引用的文档

问题描述

我正在尝试使用 mongodb 中的聚合管道填充相关字段,普通关系也可以工作(我的意思是 oid 引用其他集合中的 oid)但是当你有一个对象数组,其属性之一引用子文档时会发生什么. 如果我不清楚,这里有一点代表。

假设我有以下架构:

Profile {
    _id: {
        type: mongoose.Schema.Types.ObjectId
    },
    Gender: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "Gender"
    },
    PhoneNo: [
        Value: {
            type: String
        },
        PhoneType: {
            type: mongoose.Schema.Types.ObjectId,
            ref: "PhoneType"
        }
    ]
}

PhoneType {
    _id: {
        type: mongoose.Schema.Types.ObjectId
    },
    Name: {
        type: String
    }
}

Gender {
    _id: {
        type: mongoose.Schema.Types.ObjectId
    },
    Name: {
        type: String
    }
}

所以,我想得到如下结果:

    {
        _id: $oid,
        Gender: {Value:"Masculine"},
        PhoneNo: {
            Value: "000000",
            PhoneType: {
                _id: $oid
                Name: "Cell"
            }
        }
    },
    {
        _id: $oid,
        Gender: {Value:"Feminine"},
        PhoneNo: {
            Value: "999999",
            PhoneType: {
                _id: $oid
                Name: "Work"
            }
        }
    }

在 Gender 中查找效果很好,但是当我尝试查找 PhoneNo 时,我丢失了value属性。

我得到的是:

注意字段/属性Value,丢失。

    {
       _id: $oid,
       Gender: {Value:"Masculine"},
       PhoneNo: [{
         PhoneType: {
            _id: $oid
            Name: "Cell"
         }
       }]
    },

    {
       _id: $oid,
       Gender: {Value:"Feminine"},
       PhoneNo: [{
         PhoneType: {
            _id: $oid
            Name: "Work"
         }
       }]
    }

这是我使用的代码:

{
  from: 'PhoneType',
  'let': {"ids":"$PhoneNo.PhoneType"},
  "pipeline": [
    { "$match": { "$expr": { "$in": ["$_id", "$$ids"] } } },
  ],
  as: "PhoneNo"
}

我怎样才能做到这一点?:S

标签: node.jsmongodbmongoosemongodb-query

解决方案


所以这是您问题的演练,我们还在查找中包含 Values let 声明它将是一个数组,因为它存储在一个数组中,在项目阶段我们将获取 indexOf Values 数组,其中 $$ROOT 的 id 和 id 匹配

https://mongoplayground.net/p/UUXus3N3ncw

输入集合:

"user": [
    {
      _id: {
        type: "1"
      },
      Gender: 12,
      PhoneNo: [
        {
          Value: "name",
          PhoneType: 21
        },
        {
          Value: "name2",
          PhoneType: 212
        }
      ]
    }
  ],
  "gender": [
    {
      "_id": 12,
      "Name": "Male"
    }
  ],
  "PhoneType": [
    {
      "_id": 21,
      name: "Sus",
      val: "750"
    },
    {
      "_id": 212,
      name: "Suss",
      val: "7500"
    }
  ]

聚合管道:

user.aggregate([
  {
    $lookup: {
      from: "PhoneType",
      "let": {
        "ids": "$PhoneNo.PhoneType",
        "val": "$PhoneNo.Value",

      },
      "pipeline": [
        {
          "$match": {
            "$expr": {
              "$in": [
                "$_id",
                "$$ids"
              ]
            }
          }
        },
        {
          $project: {
            _id: 0,
            Value: {
              $arrayElemAt: [
                "$$val",
                {
                  $indexOfArray: [
                    "$$ids",
                    "$$ROOT._id"
                  ]
                }
              ]
            },
            PhoneType: "$$ROOT"
          }
        }
      ],
      as: "PhoneNo"
    }
  }
])

输出结果:

[
  {
    "Gender": 12,
    "PhoneNo": [
      {
        "PhoneType": {
          "_id": 21,
          "name": "Sus",
          "val": "750"
        },
        "Value": "name"
      },
      {
        "PhoneType": {
          "_id": 212,
          "name": "Suss",
          "val": "7500"
        },
        "Value": "name2"
      }
    ],
    "_id": {
      "type": "1"
    }
  }
]

推荐阅读