Mongodb在_id字段上从字符串连接到ObjectId
我有两套Mongodb在_id字段上从字符串连接到ObjectId,mongodb,join,mongodb-query,aggregation-framework,lookup,Mongodb,Join,Mongodb Query,Aggregation Framework,Lookup,我有两套 使用者 { "_id" : ObjectId("584aac38686860d502929b8b"), "name" : "John" } 角色 { "_id" : ObjectId("584aaca6686860d502929b8d"), "role" : "Admin", "userId" : "584aac38686860d502929b8b" } 我想根据用户id(在角色集合中)\u id(在用户集合中)加入这些集合 我尝试了以下查询:
{
"_id" : ObjectId("584aac38686860d502929b8b"),
"name" : "John"
}
{
"_id" : ObjectId("584aaca6686860d502929b8d"),
"role" : "Admin",
"userId" : "584aac38686860d502929b8b"
}
db.role.aggregate({
"$lookup": {
"from": "user",
"localField": "userId",
"foreignField": "_id",
"as": "output"
}
})
只要我将userId存储为ObjectId,就会得到预期的结果。当我的userId是字符串时,没有结果。
Ps:我试过了
foreignField:“_id”.valueOf()
及
foreignField:“_id”.toString()
。但是基于ObjectId字符串字段匹配/连接没有运气
任何帮助都将不胜感激。从MongoDB 3.4开始,这是不可能的。此功能已被请求,但尚未实现。以下是相应的门票:
编辑 以前的票证是在MongoDB 4.0中修复的。现在,您可以通过以下查询实现这一点:
db.user.aggregate([
{
"$project": {
"_id": {
"$toString": "$_id"
}
}
},
{
"$lookup": {
"from": "role",
"localField": "_id",
"foreignField": "userId",
"as": "role"
}
}
])
结果:
[
{
"_id": "584aac38686860d502929b8b",
"role": [
{
"_id": ObjectId("584aaca6686860d502929b8d"),
"role": "Admin",
"userId": "584aac38686860d502929b8b"
}
]
}
]
在线试用:您可以使用mongodb的聚合4.0将字符串id
转换为ObjectId
db.role.aggregate([
{ "$lookup": {
"from": "user",
"let": { "userId": "$_id" },
"pipeline": [
{ "$addFields": { "userId": { "$toObjectId": "$userId" }}},
{ "$match": { "$expr": { "$eq": [ "$userId", "$$userId" ] } } }
],
"as": "output"
}}
])
或者,您可以使用mongodb4.0中的聚合,该聚合将ObjectId
转换为String
db.role.aggregate([
{ "$addFields": { "userId": { "$toString": "$_id" }}},
{ "$lookup": {
"from": "user",
"localField": "userId",
"foreignField": "userId",
"as": "output"
}}
])
我认为前面的答案在
$toObjectId
案例中有一个错误。let
语句适用于调用函数aggregate
的db集合(即“角色”),而不适用于由“from”(即“用户”)指向的集合
或
及
请注意,这2个聚合运算符仅在4中可用。0@AnthonyWinzlet这应该是公认的答案。您好@ash,您在
cond
中的括号错误,这应该可以:
db.role.aggregate([
{ "$lookup": {
"let": { "userObjId": { "$toObjectId": "$userId" } },
"from": "user",
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$userObjId" ] } } }
],
"as": "userDetails"
}}
])
db.role.aggregate([
{ "$project": { "userObjId": { "$toObjectId": "$userId" } } },
{ "$lookup": {
"localField": "userObjId",
"from": "user",
"foreignField": "$_id",
"as": "userDetails"
}}
])
db.user.aggregate([
{ "$project": { "userStrId": { "$toString": "$_id" }}},
{ "$lookup": {
"localField": "userStrId",
"from": "role",
"foreignField": "userId",
"as": "roleDetails"
}}
])