Solución:
Puedes usar $toObjectId
agregación de mongodb 4.0 que convierte String id
para ObjectId
db.role.aggregate([
{ "$lookup": {
"from": "user",
"let": { "userId": "$_id" },
"pipeline": [
{ "$addFields": { "userId": { "$toObjectId": "$userId" }}},
{ "$match": { "$expr": { "$eq": [ "$userId", "$$userId" ] } } }
],
"as": "output"
}}
])
O puedes usar $toString
agregación de mongodb 4.0 que convierte ObjectId
para String
db.role.aggregate([
{ "$addFields": { "userId": { "$toString": "$_id" }}},
{ "$lookup": {
"from": "user",
"localField": "userId",
"foreignField": "userId",
"as": "output"
}}
])
Esto no es posible a partir de MongoDB 3.4. Esta función ya se solicitó, pero aún no se ha implementado. Aquí están las entradas correspondientes:
- SERVER-22781: Permitir búsqueda de $ entre ObjectId (_id.str) y cadena
- SERVER-24947: Necesita un mecanismo de conversión de tipo para booleanos, ISODates, ObjectID
Por ahora, tendrá que almacenar userId como ObjectId
EDITAR
Los tickets anteriores se arreglaron en MongoDB 4.0. Ahora puede lograr esto con la siguiente consulta:
db.user.aggregate([
{
"$project": {
"_id": {
"$toString": "$_id"
}
}
},
{
"$lookup": {
"from": "role",
"localField": "_id",
"foreignField": "userId",
"as": "role"
}
}
])
resultado:
[
{
"_id": "584aac38686860d502929b8b",
"role": [
{
"_id": ObjectId("584aaca6686860d502929b8d"),
"role": "Admin",
"userId": "584aac38686860d502929b8b"
}
]
}
]
Pruébelo en línea: mongoplayground.net/p/JoLPVIb1OLS
Creo que la respuesta anterior tiene un error en el caso ‘$ toObjectId’. los let
declaración se aplica a la colección db en la que la función aggregate
se llama (es decir, ‘rol’) y no en la colección señalada por “desde” (es decir, ‘usuario’).
db.role.aggregate([
{ "$lookup": {
"let": { "userObjId": { "$toObjectId": "$userId" } },
"from": "user",
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$userObjId" ] } } }
],
"as": "userDetails"
}}
])
O
db.role.aggregate([
{ "$project": { "userObjId": { "$toObjectId": "$userId" } } },
{ "$lookup": {
"localField": "userObjId",
"from": "user",
"foreignField": "$_id",
"as": "userDetails"
}}
])
Y
db.user.aggregate([
{ "$project": { "userStrId": { "$toString": "$_id" }}},
{ "$lookup": {
"localField": "userStrId",
"from": "role",
"foreignField": "userId",
"as": "roleDetails"
}}
])