英文:
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"
}
}
])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论