Buscar documentos MongoDB con Python

Para buscar documentos en nuestras colecciones de MongoDB podemos hacer uso de find() y de find_one().

  • Con find_one() estaremos encontrando el primer documento que cumpla con una determinada condición.
  • Con find() estaremos encontrando todos los documentos que cumplan una determinada condición.

Para determinar las condiciones en nuestras búsquedas tenemos que ayudarnos de los operadores. Existen varios tipos de operadores que hacen que las combinaciones sean prácticamente infinitas.

Operadores MongoDB

Operadores de comparación

OperadorSignificadoEquivale
$eqigual a==
$neno es igual a!=
$gtmayor que>
$gtemayor o igual que>=
$ltmenor que<
$ltemenor o igual que<=
Tabla operadores de comparación

Vamos a ver el primer ejemplo con find() para buscar documentos que cumplan determinadas condiciones.

Para poder hacer búsquedas primero tenemos que crear una colección y dentro de ésta crear algunos documentos.

Podemos crear la colección con documentos de la siguiente forma, será la colección que vamos a utilizar para casi todos los ejemplos que veamos en esta entrada.

import pymongo

mi_compass = pymongo.MongoClient('mongodb+srv://user:[email protected]/test?authMechanism=DEFAULT')
mi_ddbb = mi_compass['ddbb_oyoladev']

import uuid
import random
documentos = []
for i in range(20):
    mi_id = uuid.uuid4().hex
    if i <= 10:
        numero = random.randint(100, 200)
        documentos.append({'_id': mi_id, 'numero': numero})
    else:
        numero = random.randint(200, 300)
        documentos.append({'_id': mi_id, 'numero': numero})

mi_coleccion = mi_ddbb['aleatorios']
insertando = mi_coleccion.insert_many(documentos)

Si vamos a Compass podemos ver que se han creado correctamente nuestros veinte documentos, diez documentos con el valor del campo ‘numero’ entre cien y doscientos y otros diez documentos con el valor del campo ‘numero’ entre doscientos y trescientos.

Ya tenemos la colección aleatorio con veinte documentos, ahora toca buscar documentos.

find_one() con PyMongo

Para comenzar buscaremos con find_one() un documento determinado utilizando un operador de comparación, compararemos su campo ‘_id’.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { '_id': 'e5a9d0022e124b40b8bbb1c2969dfaf9' }
resultado = mi_coleccion.find_one(identifico)
print(resultado)

# {'_id': 'e5a9d0022e124b40b8bbb1c2969dfaf9', 'numero': 140}

find() con PyMongo

Ahora buscaremos con find() todos los documentos que cumplan una determinada condición, la condición será que que el valor del campo ‘numero’ sea mayor de cien pero menor que ciento cincuenta.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { 'numero': { '$gt': 100, '$lt': 150}}
resultado = mi_coleccion.find(identifico)
for documento in resultado:
    print(documento)

# {'_id': '0ae723c4781c458da9fa64d12a3c746f', 'numero': 117}
# {'_id': 'e5a9d0022e124b40b8bbb1c2969dfaf9', 'numero': 140}
# {'_id': '257a3f246ab44c9d8278f011b61a45e0', 'numero': 127}
# {'_id': 'abb3dd0bee0f4a01b0178607c165c1f8', 'numero': 119}

Podemos utilizar tantos operadores de comparación como necesitemos para buscar los documentos exactos.

Operadores de pertenencia

OperadorSignificadoEquivale
$inEnIn
$ninNo enNot in
Tabla operadores de pertenencia

Vamos a ver el primer ejemplo buscando un solo documento con find_one() y los operadores de pertenencia.

Buscaremos el primer documento que encuentre que el valor del campo ‘numero’ esté entre ciento dieciséis y ciento diecinueve, para esto tendremos que colocar una lista con estos valores.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { 'numero': {'$in': [116, 117, 118, 119]} }
resultado = mi_coleccion.find_one(identifico)
print(resultado)

# {'_id': '0ae723c4781c458da9fa64d12a3c746f', 'numero': 117}

Ahora realizaremos el mismo ejemplo pero utilizando find() mostraremos los documentos que su valor en el campo ‘numero’ esté entre ciento dieciséis y ciento diecinueve.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { 'numero': {'$in': [116, 117, 118, 119]} }
resultado = mi_coleccion.find(identifico)
for documento in resultado:
    print(documento)

# {'_id': '0ae723c4781c458da9fa64d12a3c746f', 'numero': 117}
# {'_id': 'abb3dd0bee0f4a01b0178607c165c1f8', 'numero': 119}

Operadores de elementos y de tipos de elementos

OperadorSignificado
$typeTipo Tipos de campo MongoDB
(string, int32, int64, double, date, code…)
$existsExisteTrue / False
Tabla operadores de elementos y tipos de elementos

Podemos hacer búsquedas de documentos basándonos la existencia de un campo o de un tipo de campo.

Para ver este operador modificaremos el tipo del campo ‘numero’ para uno de nuestros documentos. También modificaremos otro documento diferente agregando un nuevo campo llamado ‘otro_campo’ que solo tenga él.

Así queda nuestra colección con esta modificación.

Operadores de elementos

Realizaremos un ejemplo buscando documentos en los que el tipo de campo ‘numero’ sea string, obviamente solo nos aparecerá uno, el que acabamos de modificar.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { 'numero': {'$type': 'string'} }
resultado = mi_coleccion.find(identifico)
for documento in resultado:
    print(documento)

# {'_id': 'e5a9d0022e124b40b8bbb1c2969dfaf9', 'numero': '140'}

Ahora buscaremos documentos que contentan el campo ‘otro_campo’, de la misma forma solo nos aparecerá el que acabamos de modificar.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { 'otro_campo': {'$exists': True} }
resultado = mi_coleccion.find(identifico)
for documento in resultado:
    print(documento)

# {'_id': '43d8d4e129fc4e1f96252715a7086fbd', 'numero': 196, 'otro_campo': 'cualquier valor'}

Operadores lógicos

OperadorSignificadoEquivale
$andycumplen todas las condiciones
$notnono cumplen la condición
$nornono cumplen ninguna condición
$oralgunocumplen alguna condición
$notinvierteinvierte el efecto del operador
Tabla operadores lógicos

Con los operadores lógicos podemos crear condiciones mucho más elaboradas, vamos a ver un ejemplo que devuelve los documentos en los que el valor de ‘numero’ es mayor de cien y menor de ciento noventa.

Voy a darle esta indentación a ‘identifico’ para que se entienda mejor.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { 
                '$and': [
                    { 'numero': {'$gt': 100} },
                    { 'numero': {'$lt': 190} }
                ]
            }

resultado = mi_coleccion.find(identifico)
for documento in resultado:
    print(documento)

# {'_id': '0ae723c4781c458da9fa64d12a3c746f', 'numero': 117}
# {'_id': '5130e9b3ccc74e58bebf927776a7b691', 'numero': 187}
# {'_id': '8b4dc7319d8a474fb04ad77a561b491e', 'numero': 180}
# {'_id': '257a3f246ab44c9d8278f011b61a45e0', 'numero': 127}
# {'_id': 'ce0f5a45bf3247c59d35c22200c6fe48', 'numero': 179}
# {'_id': 'abb3dd0bee0f4a01b0178607c165c1f8', 'numero': 119}
# {'_id': '5b1aaba9c5624c748e1bf32d804b3aaa', 'numero': 185}
# {'_id': '96e73fa186604479a1bc20f0cd09073f', 'numero': 173}

Operador de evaluación de expresiones regulares $regex

$regexEquivale
^Comenzar desde el principio
.Comodín para cualquier caracter
* Cualquier caracter varias veces

Vamos a ver un ejemplo utilizando el operador $regex con MongoDB.

Buscaremos documentos en nuestra colección, en los que el primer valor del ‘_id’ sea un número cinco. Para esto la expresión regular que escribiremos en la condición será muy sencilla, únicamente le indicaremos que comience al principio ‘^’ y que el primer valor sea un número cinco ‘5’.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { '_id': {'$regex': '^5'} }
resultado = mi_coleccion.find(identifico)
for documento in resultado:
    print(documento)

# {'_id': '5130e9b3ccc74e58bebf927776a7b691', 'numero': 187}
# {'_id': '5b1aaba9c5624c748e1bf32d804b3aaa', 'numero': 185}

Ha encontrado dos resultados en los que el ‘_id’ comienza por el número cinco.

Mostrando determinados campos en las búsquedas

En todos los ejemplos que estamos viendo cuando visualizamos el resultado nos muestra el documento completo con todos sus campos. Existe la posibilidad de elegir qué campos mostrar indicándosele mediante el valor cero o uno.

Vamos a verlo con un ejemplo en el que omitiremos que nos devuelva el campo ‘_id’ colocándolo a cero y sí el campo ‘numero’ poniéndolo a uno.

mi_coleccion = mi_ddbb['aleatorios']
identifico = { '_id': {'$regex': '^5'} }
resultado = mi_coleccion.find(identifico, {'_id':0, 'numero': 1})
for documento in resultado:
    print(documento)

# {'numero': 187}
# {'numero': 185}

Ordenar documentos sort MongoDB

Podemos ordenar los resultados de nuestras búsquedas de documentos con .sort().

Vamos a ver un ejemplo en el que ordenaremos nuestros resultados por el campo ‘numero’.

mi_coleccion = mi_ddbb['aleatorios']
resultado = mi_coleccion.find().sort('numero')
for documento in resultado:
    print(documento)

# {'_id': '0ae723c4781c458da9fa64d12a3c746f', 'numero': 117}
# {'_id': 'abb3dd0bee0f4a01b0178607c165c1f8', 'numero': 119}
# ...
# {'_id': '2f10b32d877044cda9fbe92259263ad9', 'numero': 294}
# {'_id': 'd24563a5a2be4a7e946f0a3fae088082', 'numero': 294}

Podemos indicarle que el orden sea descendiente si agregamos menos uno como argumento.

mi_coleccion = mi_ddbb['aleatorios']
resultado = mi_coleccion.find().sort('numero', -1)
for documento in resultado:
    print(documento)

# {'_id': '2f10b32d877044cda9fbe92259263ad9', 'numero': 294}
# {'_id': 'd24563a5a2be4a7e946f0a3fae088082', 'numero': 294}
# ...
# {'_id': 'abb3dd0bee0f4a01b0178607c165c1f8', 'numero': 119}
# {'_id': '0ae723c4781c458da9fa64d12a3c746f', 'numero': 117}

Limitar resultados limit MongoDB

Para limitar el número de resultados podemos usar limit() y nos devolverá solo el número de documentos que pasemos como argumento.

Para este ejemplo le indicaremos que ordene el resultado de forma ascendente y que limite el número de documentos a tres.

mi_coleccion = mi_ddbb['aleatorios']
resultado = mi_coleccion.find().sort('numero').limit(3)
for documento in resultado:
    print(documento)

# {'_id': '0ae723c4781c458da9fa64d12a3c746f', 'numero': 117}
# {'_id': 'abb3dd0bee0f4a01b0178607c165c1f8', 'numero': 119}
# {'_id': '257a3f246ab44c9d8278f011b61a45e0', 'numero': 127}

Dejar un comentario

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