英文:
Auto conversion of foreign key from string to ObjectId to make $lookup aggregation work by MongoDB
问题
我有两个集合,我正在使用其中一个集合的_id字段作为外键在另一个集合中。但_id是Object,在另一个集合中是string,所以$lookup无法匹配。
集合1:User集合
{ "_id" : ObjectId("6471bf9db77f0b33a9b0bd38"), "name" : "Alok", "city" : "someCity" }
集合2:Order集合
{ "_id" : ObjectId("6471bfd4b77f0b33a9b0bd39"), "uid" : "6471bf9db77f0b33a9b0bd38", "product" : "product1" }
我尝试使用$lookup
db.order.aggregate([{$lookup: {from: 'users', localField:'uid', foreignField:'_id', as:'join'}}])
这个$lookup不起作用,因为_id是Object,而uid是string。
这是一个常见的需求,所以必须有一种自动化的方法,因为我不想使用长的pipeline。
如何快速修复使这个$lookup工作,而不使用长的pipeline?
英文:
I have two collections and I am using one of collections _id field as foreign key in other collection. But _id is Object and in in other collection it is string so $lookup is not able to match.
Collection 1: User collection
{ "_id" : ObjectId("6471bf9db77f0b33a9b0bd38"), "name" : "Alok", "city" : "someCity" }
Collection 2: Order collection
{ "_id" : ObjectId("6471bfd4b77f0b33a9b0bd39"), "uid" : "6471bf9db77f0b33a9b0bd38", "product" : "product1" }
I am trying to use $lookup
db.order.aggregate([{$lookup: {from: 'users', localField:'uid', foreignField:'_id', as:'join'}}])
This $lookup does not work because _id is Object and uid is string.
This is common requirement so there must be some automated way as I dont want to use $lookup with long pipeline.
What can quickest fix to make this $lookup work without using long pipeline?
答案1
得分: 1
如评论中所提到的,您需要在 $lookup 阶段之前使用 $set 阶段将 uid 转换为 ObjectId 类型。
{
"$set": {
"uid": {
"$toObjectId": "$uid"
}
}
}
否则,您也可以使用带有管道的 $lookup。
{
"$lookup": {
"from": "users",
"let": {
"uid": {
"$toObjectId": "$uid"
}
},
"pipeline": [
{
"$match": {
"$expr": {
"$eq": [
"$_id",
"$$uid"
]
}
}
}
],
"as": "join"
}
}
英文:
As mentioned in the comment, you need a $set stage to convert the uid to ObjectId type before $lookup stage.
db.order.aggregate([
{
$set: {
uid: {
$toObjectId: "$uid"
}
}
},
{
$lookup: {
from: "users",
localField: "uid",
foreignField: "_id",
as: "join"
}
}
])
Otherwise, you may use $lookup with pipeline as well.
db.order.aggregate([
{
$lookup: {
from: "users",
let: {
uid: {
$toObjectId: "$uid"
}
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$_id",
"$$uid"
]
}
}
}
],
as: "join"
}
}
])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论