Seleccionar documentos que tengan un campo en MongoDB con $exists

Si queremos seleccionar documentos que tengan un campo en MongoDB, podemos hacerlo de un modo muy sencillo con un poco de código. Voy a mostraros un ejemplo de un documento albergado en la base de datos dtc y colección coches. Después de importar los documentos, podéis ver la estructura que tendría uno de ellos.

{
    "_id": {
        "$oid": "5e7b723cbcbdbb32d75de47e"
    },
    "meta": {
        "account": "vivaelsoftwarelibre", "event": "track"
    },
    "payload": {
        "id": {
            "$numberLong": "1323179130388349400"
        },
        "connection_id": {
            "$numberLong": "1323178914641609000"
        },
        "id_str":"1323179130388349323",
        "connection_id_str":"132317xxxxxxx609032",
        "index": {
            "$numberInt": "424"
        },
        "asset":"35623205xxxxxxx",
        "recorded_at":"2019-12-31T06:40:01Z",
        "recorded_at_ms":"2019-12-31T06:40:01.000Z",
        "received_at":"2019-12-31T06:41:28Z",
        "fields": {
            "MDI_CUSTOM_PID_7": {
                "b64_value": "MjIwMTQwOTc2NjM3NzM5MDA4"
            },
            "OBD_CONNECTED_PROTOCOL": {
                "b64_value": "AAAABg=="
            },
            "MDI_EXT_BATT_LOW": {
                "b64_value": "AA=="
            }
        }
    }
}

En nuestra colección dtc tenemos más de dos millones de documentos como el anterior, y queremos seleccionar solo aquellos documentos que tengan algún campo o algunos campos exclusivamente.

Seleccionar documentos que tengan un campo en MongoDB: $exists

Para poder seleccionar aquellos documentos que tengan un campo específico, tenemos que emplear el operador $exists. Este operador llevará el valor de true ($exists: true), ya que queremos que nos devuelvan los documentos que sí existen con ese campo.

Campos no embebidos

Si queremos seleccionar todos los documentos que contengan el campo meta, procedemos del siguiente modo:

db.getCollection("dtc").find({"meta": { $exists: true }})

Si lo que queremos es seleccionar todos los documentos con payload, lo hacemos de un modo similar:

db.getCollection("dtc").find({"payload": { $exists: true }})

En ambos casos, los campos meta y payload no se encuentran embebidos dentro del documento, sino que están en la raíz, como si fueran los campos primarios con mayor jerarquía.

Campos embebidos

Ahora bien, ¿qué pasa si queremos saber cuántos documentos presentan el campo MDI_CUSTOM_PID_7? Si escribimos el siguiente comando nos devuelve 0 resultados o documentos.

db.getCollection("dtc").find({"MDI_CUSTOM_PID_7": { $exists: true }})

¿Quiere esto decir que no existen documentos con ese campo? Obviamente no, tal y como hemos visto en nuestro ejemplo.

Lo que sucede es que no se encuentra ese campo MDI_CUSTOM_PID_7 fuera de los documentos embebidos. Dicho de otro modo, MDI_CUSTOM_PID_7 es un campo embebido dentro del campo payload, y éste a su vez está embebido dentro de fields.

Cuando hagamos una búsqueda de un campo embebido, tenemos que hacer referencia a los campos embebidos necesarios recorrer para llegar hasta el que nos interesa. Por ejemplo, para MDI_CUSTOM_PID_7 la ruta sería payload.fields.MDI_CUSTOM_PID_7. Finalmente, el comando con todo sería el siguiente:

db.getCollection("dtc").find({"payload.fields.MDI_CC_DIAG_DTC_LIST": { $exists: true }})

Seleccionar documentos que tengan dos o más campos en MongoDB

Si complicamos un poco más lo que hemos visto, podemos desear buscar los documentos que tengan dos campos específicos. Sería complicarlo añadiendo un segundo $exists. La base de cómo referenciar la localización de los campos es la misma que la vista anteriormente.

Ahora queremos seleccionar los documentos o registros que tengan los campos MDI_CC_DIAG_DTC_LIST y asset. El código a ejecutar sería el siguiente:

db.getCollection("dtc")
  .find({
    "payload.fields.MDI_CC_DIAG_DTC_LIST": { $exists: true },
    "payload.asset": { $exists: true }
  })

De este modo ya veis que seleccionar documentos que tengan un campo en MongoDB es muy fácil si empleamos correctamente el operador $exists.

1 comentario en “Seleccionar documentos que tengan un campo en MongoDB con $exists”

Deja un comentario