Kav*_*ali 17 lookup join mongodb aggregation-framework objectid
我有两个系列
用户
{
"_id" : ObjectId("584aac38686860d502929b8b"),
"name" : "John"
}
Run Code Online (Sandbox Code Playgroud)角色
{
"_id" : ObjectId("584aaca6686860d502929b8d"),
"role" : "Admin",
"userId" : "584aac38686860d502929b8b"
}
Run Code Online (Sandbox Code Playgroud)我想基于userId(在角色集合中) - _id(在用户集合中)加入这些集合.
我尝试了以下查询:
db.role.aggregate(
{
$lookup:
{
from: 'user',
localField: 'userId',
foreignField: '_id',
as: 'output'
}
}
);
Run Code Online (Sandbox Code Playgroud)
只要我将userId存储为ObjectId,这就给了我预期的结果.当我的userId是一个字符串时,没有结果.Ps:我试过了
foreignField:'_ id'.valueOf()
和
foreignField:'_ id'.toString()
.但是基于ObjectId-string字段匹配/加入没有运气.
任何帮助将不胜感激.
小智 30
我认为之前的答案在$toObjectId案例中存在错误。该let语句适用于aggregate调用该函数的数据库集合(即'role'),而不适用于“from”指向的集合(即'user')。
db.role.aggregate([
{ "$lookup": {
"let": { "userObjId": { "$toObjectId": "$userId" } },
"from": "user",
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$userObjId" ] } } }
],
"as": "userDetails"
}}
])
Run Code Online (Sandbox Code Playgroud)
或者
db.role.aggregate([
{ "$project": { "userObjId": { "$toObjectId": "$userId" } } },
{ "$lookup": {
"localField": "userObjId",
"from": "user",
"foreignField": "$_id",
"as": "userDetails"
}}
])
Run Code Online (Sandbox Code Playgroud)
和
db.user.aggregate([
{ "$project": { "userStrId": { "$toString": "$_id" }}},
{ "$lookup": {
"localField": "userStrId",
"from": "role",
"foreignField": "userId",
"as": "roleDetails"
}}
])
Run Code Online (Sandbox Code Playgroud)
Ash*_*shh 17
您可以使用 $toObjectIdmongodb 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"
}}
])
Run Code Online (Sandbox Code Playgroud)
或者您可以使用$toStringmongodb 4.0中的聚合转换ObjectId为String
db.role.aggregate([
{ "$addFields": { "userId": { "$toString": "$_id" }}},
{ "$lookup": {
"from": "user",
"localField": "userId",
"foreignField": "userId",
"as": "output"
}}
])
Run Code Online (Sandbox Code Playgroud)