Estoy tratando de desarmar ciertos campos según el nombre del campo (la clave).
Digamos que tengo algo como esto:
{ 5: "cool", 93: "cool", 30: "cool", 56: "cool" }¿Cómo desarmaría todos los campos con un valor por debajo de, digamos, 40?
Así que el resultado debería ser:
{ 5: "cool", 30: "cool" }Intenté usar el comando menor que en todo el campo o usar el operador posicional, pero ambos fallaron.
collection.update_one( {"_id": id}, {"$unset": {"blacklist.$": {"$lt": 40}}} )No pude encontrar nada en línea o en los documentos, así que espero encontrar ayuda aquí,
¡Gracias!
Realmente no puede usar $unset de esta manera, aún podemos lograr esto usando actualizaciones canalizadas, con una sintaxis un poco más complicada.
Nuestro enfoque será convertir nuestro objeto raíz en una matriz usando $objectToArray , iterar sobre él y filtrar todas las claves numéricas por debajo de un cierto umbral. luego, finalmente, vuelva a convertirlo en un objeto y actualice nuestro documento, así:
db.collection.update({}, [ { $replaceRoot: { newRoot: { $arrayToObject: { $filter: { input: { $objectToArray: "$$ROOT" }, cond: { $cond: [ { $regexMatch: { input: "$$this.k", regex: "^[0-9]+$" } }, { $lt: [ { $toInt: "$$this.k" }, 40 ] }, true ] } } } } } } ])Consulta
[] la $$ROOT"_id" o < 40 *esto elimina todos los campos >=40 , puede cambiar el último $lt si no lo necesita
* la respuesta de toms funciona y es más general, si tiene claves mixtas que algunas son números y otras no usan la forma de toms (esto es un poco más simple pero supone que todos los campos son números excepto el "_id")
aggregate( [{"$replaceRoot": {"newRoot": {"$arrayToObject": [{"$filter": {"input":{"$objectToArray":"$$ROOT"}, "cond": {"$or": [{"$eq":["$$this.k", "_id"]}, {"$lt":[{"$toInt":"$$this.k"}, 40]}]}}}]}}}])