Saltar al contenido

Buscar en matriz doble anidada MongoDB

Te sugerimos que pruebes esta solución en un entorno controlado antes de pasarlo a producción, un saludo.

Solución:

En el sentido más simple, esto solo sigue la forma básica de “notación de puntos” utilizada por MongoDB. Eso funcionará independientemente de cuál array miembro el interior array el miembro está dentro, siempre que coincida con un valor:

db.mycollection.find(
    "someArray.someNestedArray.name": "value"
)

Eso está bien para un valor de “campo único”, para hacer coincidir varios campos que usaría $elemMatch:

db.mycollection.find(
    "someArray":  
        "$elemMatch": 
            "name": "name1",
            "someNestedArray": 
                "$elemMatch": 
                    "name": "value",
                    "otherField": 1
                
            
        
    
)

Eso coincide con el documento que contendría algo con un campo en esa “ruta” que coincide con el valor. Si tenía la intención de “coincidir y filtrar” el resultado para que solo se devolviera el elemento coincidente, esto no es posible con la proyección del operador posicional, como se cita:

Matrices anidadas

El operador posicional $ no se puede utilizar para consultas que atraviesan más de un arraycomo consultas que atraviesan matrices anidadas dentro de otras matrices, porque el reemplazo del marcador de posición $ es un valor único

Mongo DB moderno

Podemos hacer esto aplicando $filter y $map aquí. los $map es realmente necesario porque el “interior” array puede cambiar como resultado del “filtrado” y el “exterior” array por supuesto no coincide con las condiciones cuando el “interior” fue despojado de todos los elementos.

Nuevamente, siguiendo el ejemplo de tener múltiples propiedades para hacer coincidir dentro de cada array:

db.mycollection.aggregate([
   "$match": 
    "someArray": 
      "$elemMatch": 
         "name": "name1",
         "someNestedArray": 
           "$elemMatch": 
             "name": "value",
             "otherField": 1
           
         
       
    
  ,
   "$addFields": 
    "someArray": 
      "$filter": 
        "input": 
          "$map": 
            "input": "$someArray",
            "as": "sa",
            "in": 
              "name": "$$sa.name",
              "someNestedArray": 
                "$filter": 
                  "input": "$$sa.someNestedArray",
                  "as": "sn",
                  "cond": 
                    "$and": [
                       "$eq": [ "$$sn.name", "value" ] ,
                       "$eq": [ "$$sn.otherField", 1 ] 
                    ]
                  
                
                           
            
          ,
        ,
        "as": "sa",
        "cond": 
          "$and": [
             "$eq": [ "$$sa.name", "name1" ] ,
             "$gt": [  "$size": "$$sa.someNestedArray" , 0 ] 
          ]
        
      
    
  
])

Por lo tanto, en el “exterior” array los $filter en realidad mira a la $size del “interior” array después de que fue “filtrado” en sí mismo, por lo que puede rechazar esos resultados cuando todo el interior array de hecho, coincide con la observación.

MongoDB anterior

Para “proyectar” solo el elemento coincidente, necesita el .aggregate() método:

db.mycollection.aggregate([
    // Match possible documents
     "$match": 
        "someArray.someNestedArray.name": "value"
    ,

    // Unwind each array
     "$unwind": "$someArray" ,
     "$unwind": "$someArray.someNestedArray" ,

    // Filter just the matching elements
     "$match": 
        "someArray.someNestedArray.name": "value"
    ,

    // Group to inner array
     "$group": 
        "_id":  
            "_id": "$_id", 
            "name": "$someArray.name"
        ,
        "someKey":  "$first": "$someKey" ,
        "someNestedArray":  "$push": "$someArray.someNestedArray" 
    ,

    // Group to outer array
     "$group": 
        "_id": "$_id._id",
        "someKey":  "$first": "$someKey" ,
        "someArray":  "$push": 
            "name": "$_id.name",
            "someNestedArray": "$someNestedArray"
        
     
])

Eso le permite “filtrar” las coincidencias en matrices anidadas para uno o más resultados dentro del documento.

Calificaciones y comentarios

Si te sientes incitado, tienes la libertad de dejar un ensayo acerca de qué te ha parecido este post.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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