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.

Utilice ElemMatch en la Agregación de Mongo para encontrar objetos de array nulos o que no existan.

Supongamos que tengo en Mongo 4.2 un dato como el siguiente. Ten en cuenta que cada documento consta de un array de RESULTADOS que puede contener uno o más subobjetos o nulos.

{ ” _id ” : 1, ” results ” : [ { ” product ” : ” a ” , ” score ” : ” 1 ” },
{ ” product ” : ” b ” , ” score ” : ” 5 ” }] }

{ ” _id ” : 2, ” results ” : [ { ” product ” : ” a ” , ” score ” : ” 8 ” },
{ ” product ” : ” b ” , ” score ” : ” 7 ” }] }

{ ” _id ” : 3, ” results ” : [ { ” product ” : ” a ” , ” score ” : ” ” },
{ ” product ” : ” b ” , ” score ” : } ] }

{ ” _id ” : 4, ” results ” : [ { ” product ” : ” b ” , ” score ” : ” 8 ” }] }

{ ” _id ” : 5, ” results ” : [ ] }

En este momento estoy tratando de obtener un Aggregation Pipeline con una ElemMatch para encontrar todos los documentos que tienen un Producto ” A ” con una puntuación mayor que ” ” . Eso funciona y lo estoy usando en este momento:

{ ” results ” : { $elemMatch : { ” product ” : ” a ” , ” score ” : { $gt : ‘ ‘ } } } }

Pero no puedo hacerlo de la otra manera, como todos los documentos que no tienen puntuación para el producto A. Lo cual significaría que esperaría obtener los documentos #3 y #4 y #5 del ejemplo anterior.

Puedo obtener el #3 con esto:

{ ” results ” : { $elemMatch : { ” product ” : ” a ” , ” score ” : ‘ ‘ } } }

Y el #5 con esto:

{ ” results.score ” : null }

Pero no puedo obtener el #4.
Y, por supuesto, sería lo mejor obtener el Doc #3 y #4 y #5 con una sola consulta.
Así que ¿hay alguna manera de hacerlo?

Gracias por cualquier ayuda.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para obtener todos los documentos que no tienen una puntuación para el producto A, puedes usar el operador $not en combinación con $elemMatch. Aquí tienes la estructura de consulta que debería funcionar:

    {
      $match: {
        results: {
          $not: {
            $elemMatch: {
              product: "a",
              score: { $ne: "" }
            }
          }
        }
      }
    }
    

    Esto coincidirá con todos los documentos donde el arreglo results no tiene ningún subobjeto que cumpla la condición { product: "a", score: { $ne: "" } }, lo que significa que no hay ningún subobjeto con el producto A o hay uno pero tiene una puntuación vacía.

    Ten en cuenta que esto solo coincidirá con el documento #3 y #5 en tu ejemplo. Para coincidir también con el documento #4, puedes agregar otra condición con $or, de esta manera:

    {
      $match: {
        $or: [
          {
            results: {
              $not: {
                $elemMatch: {
                  product: "a",
                  score: { $ne: "" }
                }
              }
            }
          },
          {
            results: {
              $elemMatch: {
                product: { $ne: "a" }
              }
            }
          }
        ]
      }
    }
    

    La segunda condición coincide con documentos que tienen un subobjeto con un producto distinto de A, lo que incluiría el documento #4.

Comments are closed.