Usando operadores para realizar Updates en arreglos

16/26

Lectura

En este enlace se encuentran la referencia a todos los operadores que se encuentran en MongoDb, antes de emplear l贸gica adicional para realizar una operaci贸n vale la pena echar una ojeada a la lista de operadores que en algunos casos pueden facilitar mucho las cosas.

Para realizar las relaciones entre carreras y cursos empleamos los operadores $addToSet y $pull estos operadores sirven para agregar $addToSet o retirar $pulldocumentos de un arreglo dependiendo del filtro que aplicamos.

As铆 cuando ejecutamos db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$addToSet': {'cursos': curso}}) $addToSet lo que hace es agregar el objeto curso al arreglo cursos, si el arreglo cursos no existe lo crea.

Para retirar un curso de una carrera usamos $pull de la siguiente manera db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$pull': {'cursos': {'_id': ObjectId(json['id_curso'])}}}) aqu铆 $pull recibe un filtro y todos los elementos del arreglo cursos que cumplan con ese filtro ser谩n borrados.

skip() y limit()

Si tenemos una consulta que retorna 100 documentos pero solamente necesitamos los documentos del n煤mero 20 al 30, la manera de hacerlo es usando skip() y limit().

Si tenemos 100 carreras y solamente queremos las primeras 10 podemos ejecutar db.carreras.find({}).limit(10) esta nos traer谩 las primeras 10 carreras.

Ahora si queremos las carreras ubicadas en los puestos 40 y 50 lo que debemos hacer es db.carreras.find({}).skip(40).limit(10)

Como vemos skip() y limit() son muy 煤tiles para realizar paginaciones, cuando tenemos consultas que retornan muchos documentos y que en algunos casos la totalidad de los documentos no es utilizada es buena pr谩ctica limitar el n煤mero de documentos que hacemos viajar entre nuestro cluster de base de datos y el c贸digo de nuestra aplicaci贸n. Esto puede ayudar a mejorar la velocidad con que las consultas son procesadas por la aplicaci贸n.

Ejercicios de pr谩ctica usando operadores

// Arreglo de ejemplo
use test
db.inventory.insertMany(

[{ _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] },
{ _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] },
{ _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] },
{ _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] },
{ _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }]

)

// $or
db.inventory.find({$or: [{qty: {$gt: 25}}, {qty: {$lte: 15}}]})

// $gte
db.inventory.find({qty: {$gte: 25}})

// $size
db.inventory.find({tags: {$size: 2}})

// Insertemos estos documentos de ejemplo en la colecci贸n survey
db.survey.insertMany([
{ _id: 1, results: [ { product: "abc", score: 10 }, { product: "xyz", score: 5 } ] }
{ _id: 2, results: [ { product: "abc", score: 8 }, { product: "xyz", score: 7 } ] }
{ _id: 3, results: [ { product: "abc", score: 7 }, { product: "xyz", score: 8 } ] }
])

// $elemMatch
db.survey.find(
   { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } }
)

db.survey.find(
   { results: { $elemMatch: { product: "xyz" } } }```

Aportes 24

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

el array para insertar el la colecci贸n survey tiene un peque帽o error falta separar los elementos:

b.survey.insertMany([ 
{ _id: 1, results: [ { product: "abc", score: 10 }, { product: "xyz", score: 5 } ] },
 { _id: 2, results: [ { product: "abc", score: 8 }, { product: "xyz", score: 7 } ] },
 { _id: 3, results: [ { product: "abc", score: 7 }, { product: "xyz", score: 8 } ]}
])

Para m铆 que vengo del mundo SQL es un poco complejo trabajar con las bases NoSQL; tengo muy metidas las sentencias y la forma de trabajo y hay que cambiar la forma de hacer las cosas.

hola, tengo una duda, NOTA: esta pregunta se lee mejor en los aportes de la clase, si, al parecer hay un peque帽o 鈥渂ug鈥 con las preguntas que no muestra los estilos de markdown , en fin, aqui mi pregunta:

cuando ejecutamos el query
db.survey.find( { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } } )

nos trae la siguiente informacion:

{
    "_id" : 3.0,
    "results" : [ 
        {
            "product" : "abc",
            "score" : 7.0
        }, 
        {
            "product" : "xyz",
            "score" : 8.0
        }
    ]
} ```` 

genial, sirve pero, como podria hacer una especie de proyeccion para solo traer los elementos de array que cumplan la condicion??

osea, para que no traiga tooodos los elementos del array , solamente aquellos que cumplan con la condicion que se pone primero. para que quede algo asi:

{
    "_id" : 3.0,
    "results" : [  
        {
            "product" : "xyz",
            "score" : 8.0
        }
    ]
} 

con que especie de proyeccion podria lograr eso??

yo prob茅 buscando por alli con la proyeccion
{ "results.product": 1, "results.score": 1} pero da lo mismo

db.survey.find(
   { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } },
   { "results.product": 1 , "results.score": 1}
 )

pero da lo mismo.

y lo que yo busco ya que en algun momento lo podria necesitar es

{
    "_id" : 3.0,
    "results" : [  
        {
            "product" : "xyz",
            "score" : 8.0
        }
    ]
} 

En el insert de survey, si les tira error es porque falta separar los documentos con coma :

db.survey.insertMany([
{ _id: 1, results: [ { product: "abc", score: 10 }, { product: "xyz", score: 5 } ] },
{ _id: 2, results: [ { product: "abc", score: 8 }, { product: "xyz", score: 7 } ] },
{ _id: 3, results: [ { product: "abc", score: 7 }, { product: "xyz", score: 8 } ] }
])

Entendido y funcionando, aun asi cuesta mucho acostumbrarse a hacer update, pull , cuando ya por a帽os uno hace delete from table where condicion=val. pero bueno a tener afinidad con esa nueva forma de trabajar la base de datos

Es posible retornar datos de forma intercalada. Es decir que retorne los ultimos 10, pero solo los pares o solo los impares. Se preguntaran que uso tiene, resulta que tenemos muchos datos de sensores y se van a graficar a lo largo del tiempo, si tengo una escala de meses no necesito toda esta cantidad de datos solo algunos cada dos dias por ejemplo.

Les comparto en link para el manual de MongoDB 4.4, para que lo tengan sin conexi贸n y ordenado.
Manual MongoDB

No lo v铆 en ning煤n lado, pero supuse que las siglas de cada uno significan:

$eq: Igual 鈥=鈥. (eq: EQUAL)
$gt: Mayor 鈥>鈥. (gt: GREATER THAN)
$gte: Mayor o igual 鈥>=鈥. (gte: GREATER THAN or EQUAL)
$lt: Menor 鈥<鈥. (lt: LESS THAN)
$lte: Menor o igual 鈥<=鈥. (lte: LESS THAN or EQUAL)
$ne: Diferente 鈥!=鈥. (ne: NOT EQUAL)
$in: Valores dentro de un arreglo. (in: INSIDE)
$nin: Valores que no est谩n dentro de un arreglo. (nin: NOT INSIDE)

Siempre usado SQL y hubo un punto de quiebre en como se realizan las queries, pero como todo es cuesti贸n de seguir las reglas.

Me gusta la forma de trabajar las queries, hay que prestar mucha atenci贸n al detalle

Excelente

Excelente

En // $elemMatch le hace falta cerrar con un parentesis.

db.survey.find(
   { results: { $elemMatch: { product: "xyz" } } }
)

Au铆 pueden encontrar todos los operadores

https://docs.mongodb.com/manual/reference/operator/

El ultimo falta un parentesis, quedaria asi:

db.survey.find(
   { results: { $elemMatch: { product: "xyz" } } })

馃憤馃憤馃憤馃憤

Falta adentrarme m谩s a entender mongo! aunque la verdad se que no es complicado!

Entendido.

Con respecto a los datos insertados.
驴Qu茅 resulta en cada consulta?

db.inventory.find({ item: { name: "ab"}  })

db.inventory.find({ item: { name: "ab", code: "123" }  })

Muy bien, continuemos鈥

炉\锛(銉)锛/炉

Excelente, seguimos en el curso.

Tengo una duda y seguramente la pr谩ctica me ayudar谩 a despejar la duda.

Arriba en este POST, escribieron esto:

Para retirar un curso de una carrera usamos $pull de la siguiente manera db.carreras.update_one({'_id': ObjectId(json['id_carrera'])}, {'$pull': {'cursos': {'_id': ObjectId(json['id_curso'])}}}) aqu铆 $pull recibe un filtro y todos los elementos del arreglo cursos que cumplan con ese filtro ser谩n borrados

DUDA:
驴update one recibe un filtro y a煤n as铆 borra todos los elementos que cumplan con ese filtro? 驴no deber铆a eliminar solo uno?

Buen ejercicios de Aplicacion