es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Agregar la clave mínima disponible al diccionario de MongoDB.

Tengo documentos en una colección que tienen la siguiente estructura:

{key: {0: 2, 1: 5, 2: 100, 4: 15}}

Necesito agregar un par key: value al diccionario. value puede ser cualquier cosa. No importa. Pero key debe ser el entero más pequeño que no se usa en el diccionario como clave (comenzando desde 0).

Lo puedo hacer usando Python.

document = {key: {0: 2, 1: 5, 2: 100, 4: 15}}
new_key = 0  # clave para insertar en nuestro diccionario
for i in range(max(document['key'].keys()) + 2):
    if i not in document['key'].keys():
        new_key = i

# Actualiza el documento
document['key'][new_key] = value  # El valor puede ser cualquier cosa

¿Cómo se puede hacer usando MongoDB? ¿Es posible?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible añadir un par clave-valor al diccionario en MongoDB. Podemos usar los operadores $min y $not para encontrar el entero no utilizado más pequeño como clave y el operador $set para añadir el nuevo par clave-valor al documento.

    Aquí hay un ejemplo de consulta para lograr esto:

    db.collection.update(
       {_id: document_id},
       {$set: {[`key.${db.collection.aggregate([{
          $match: {_id: document_id},
          $project: {
             range: {$range: [0, {$add: [{$size: "$key"}, 2]}]}
          }},{
          $lookup: {
             from: "collection",
             let: {range: "$range"},
             pipeline: [
                {$match: {_id: document_id}},
                {$project: {used_keys: {$setDifference: [{$setUnion: [{$objectToArray: "$key.k"}, db.collection.distinct("_id")]}, "$$range"]}}}
             ],
             as: "used_keys"
          }},{
          $unwind: "$used_keys"
       },{
          $match: {$expr: {$lt: [{$min: {$setDifference: ["$$range", "$used_keys.used_keys"]}}, {$size: "$range"}]}}
       },{
          $replaceRoot: {newRoot: {$min: {$setDifference: ["$$range", "$used_keys.used_keys"]}}}
       }])}`]: value}}
    )
    

    Esta consulta primero crea un rango de enteros desde 0 hasta el tamaño actual del diccionario key más 2. Luego busca las claves usadas en el diccionario key usando los operadores $setDifference y $setUnion. La consulta encuentra entonces el entero más pequeño que no está en la matriz de claves usadas usando el operador $min y establece la nueva clave con ese valor usando el operador $set.

    Tenga en cuenta que esta consulta requiere MongoDB versión 3.6 o superior para el operador $min y otras etapas de canalización de agregación utilizadas en la consulta.

Comments are closed.