Saltar al contenido

Mongodb Join en el campo _id de String a ObjectId

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"
  }}
])
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *