Consulta de documentos con tamaño de matriz mayor que 1 en MongoDB

Tahseen Tauseef 20 junio 2023
  1. Data de muestra
  2. Utilice el operador $size para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB
  3. Use el operador $where para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB
  4. Use la notación de puntos para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB
  5. Use $expr (3.6+) para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB
  6. Use el operador de agregación $facet para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB
Consulta de documentos con tamaño de matriz mayor que 1 en MongoDB

Cuando trabaje en proyectos en los que necesite verificar el tamaño de la matriz o encontrar un elemento cuyo tamaño sea mayor o menor que una longitud específica, se pueden usar operadores de MongoDB como $size, $where, $exists.

Los enfoques que se analizan a continuación pueden ayudarlo a resolver el problema de la longitud o el tamaño de la matriz.

Data de muestra

Supongamos que tenemos los siguientes datos. Usaremos estos datos de muestra para consultar documentos con un tamaño de matriz particular en MongoDB.

db.inventory.insertMany([

{ item: "journal", qty: 25, tags: ["blank", "reds"], book: { author:`xyz`, price:50, location:[`india`, `USA`, `nepal`]} },

{ item: "notebook", qty: 50, tags: ["reds", "blank"], book: { author:`xyz`, price:50, location:[`india`, `usa`]} },

{ item: "paper", qty: 100, tags: ["reds", "blank", "plain"], book: { author:`xyz`, price:50, location:[]}},
{ item: "planner", qty: 75, tags: ["blank", "reds"], book: { author:`xyz`, price:50, location:[`india`]} },

{ item: "postcard", qty: 45, tags: ["blue"], book:{} }
]);

Utilice el operador $size para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB

La clase de operador de matriz en MongoDB comprende muchos operadores que se utilizan para obtener documentos haciendo referencia a matrices; $size es uno de ellos. El operador $size se utiliza para obtener un documento que contiene un campo de matriz de un tamaño específico.

Solo funciona con arreglos y acepta valores numéricos como parámetros.

Las siguientes son las funciones principales del operador $size:

  1. Comienza comparando un campo de matriz con el tamaño proporcionado por el usuario y luego continúa.
  2. Recupera los documentos que contienen los campos que cumplen el paso anterior.

Sintaxis:

{array-field: {$size: <length-of-array>}}

En este caso, array-field es el nombre del campo deseado en un documento, y length-of-array es cualquier número numérico que coincida con la longitud.

A continuación se comparten algunos ejemplos para ver cómo usar el operador $size en MongoDB.

Buscar elementos donde la longitud de las etiquetas sea 1

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

Producción:

$ tamaño 1

Buscar elementos donde la longitud de books.location sea 1

db.inventory.find({books.location:{$size:1}}

Producción:

$ tamaño 2

Use el operador $where para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB

Para proporcionar una cadena que contenga una expresión de JavaScript o una función de JavaScript completa para el sistema de consulta, utilice el operador $where. Permite una mayor flexibilidad, pero necesita que la base de datos realice la expresión o función de JavaScript para cada documento de la colección.

Haga referencia al registro en la expresión o función de JavaScript utilizando this u obj.

Sintaxis:

{ $where: <string|JavaScript Code> }

A continuación se dan ejemplos para mostrar el funcionamiento del operador $where.

Buscar elementos donde la longitud de las etiquetas sea 1

db.inventory.find({tags:{$where:`this.tags.length == 1`}}

Producción:

$donde 1

Buscar elementos donde la longitud de las etiquetas sea mayor o igual a 1

db.inventory.find({tags:{$where:`this.tags.length >= 1`}}

Buscar elementos donde la longitud de books.location sea 1

you cannot check this with the help of $where

Utilice el operador de consulta $where solo en documentos de nivel superior. No funcionará dentro de una página anidada.

Use la notación de puntos para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB

Para acceder a los elementos de la matriz y los campos de un documento incrustado, MongoDB emplea la notación de puntos.

Acceder a los elementos de la matriz

Para especificar o acceder a un elemento de matriz por su posición de índice de base cero, concatene el nombre de la matriz con el punto (.) y la posición de índice de base cero, luego escríbalo entre comillas.

Sintaxis:

"<array>.<index>"

Por ejemplo, considere el siguiente campo en un documento.

{
   ...
   contribs: [ "Turing machine", "Turing test", "Turingery" ],
   ...
}

Utilice la notación de puntos "contribs.2" para identificar el tercer miembro en la matriz contribs.2.

Buscar elementos donde la longitud de las etiquetas sea mayor que 0

db.inventory.find({tags.0:{$exists:true`}}
It will look for elements with at least one tag // array with a zero-based index.

Buscar elementos donde la longitud de books.location sea mayor que 1

db.invantory.find({book.location.1: {$exists:true}}
// It looks for all components in whose book. There are at least two elements to a place.

Use $expr (3.6+) para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB

Sintaxis:

{ $expr: { <expression> } }

Buscar documento donde la longitud de $tags sea mayor que 0

db.invantory.find({
    $expr: {
        $gt: [{ $size: { $ifNull: ["$tags", []] } }, 0]
    }
})

Buscar elementos donde la longitud de $books.location sea mayor que 1

db.invantory.find({
    $expr: {
        $gt: [{ $size: { $ifNull: ["$book.location", []] } }, 1]
    }
})
// $ifNull: ["$book.location", []] this is used to avoid any error if book.location is null

Use el operador de agregación $facet para consultar documentos con un tamaño de matriz mayor que 1 en MongoDB

Este operador procesa numerosas agregaciones sobre el mismo conjunto de documentos de entrada en una sola etapa. Cada tubería tiene su campo en el documento de salida, donde los resultados se guardan como una matriz de documentos.

La etapa $facet permite la creación de agregaciones multifacéticas que caracterizan los datos en varias dimensiones, o facetas, dentro de una sola etapa de agregación. Las agregaciones multifacéticas proporcionan múltiples filtros y categorizaciones para ayudar en la exploración y el análisis de datos.

Por ejemplo, los minoristas suelen utilizar facetas para reducir los resultados de búsqueda mediante la creación de filtros basados en el precio del producto, el fabricante, el tamaño, etc.

Los documentos de entrada solo se envían una vez al paso $facet. $facet permite numerosas agregaciones en el mismo conjunto de documentos de entrada sin necesidad de recuperarlos varias veces.

Sintaxis:

{ $facet:
   {
      <outputField1>: [ <stage1>, <stage2>, ... ],
      <outputField2>: [ <stage1>, <stage2>, ... ],
      ...

   }
}

Ingrese el nombre del campo de salida para cada tubería.

Cada canal secundario en $facet recibe el conjunto idéntico de documentos de entrada. Estos subcanales son independientes entre sí y las matrices de documentos producidas por cada uno se almacenan en diferentes campos del documento de salida.

Dentro de la misma etapa $facet, la salida de un canal secundario no se puede utilizar como entrada para otro canal secundario. Agregue etapas adicionales después de $facet e indique el nombre del campo, outputField>, de la salida de canalización secundaria deseada si se necesitan agregaciones adicionales.

Uso del Índice en la Etapa $facet

Incluso si sus canalizaciones secundarias utilizan $match o si $facet es el paso inicial en la canalización, la etapa $facet y sus canalizaciones secundarias no pueden usar índices. Durante la ejecución, la etapa $facet siempre hace un COLLSCAN.

Considere una tienda en línea cuyo inventario se almacena en la siguiente colección de obras de arte:

{ "_id" : 1, "title" : "The Pillars of Society", "artists" : "Grosz", "year" : 1926,
  "price" : NumberDecimal("199.99"),
  "tags" : [ "painting", "satire", "Expressionism", "caricature" ] }
{ "_id" : 2, "title" : "Melancholy III", "artists" : "Munch", "year" : 1902,
  "price" : NumberDecimal("280.00"),
  "tags" : [ "woodcut", "Expressionism" ] }
{ "_id" : 3, "title" : "Dancer", "artists" : "Miro", "year" : 1925,
  "price" : NumberDecimal("76.04"),
  "tags" : [ "oil", "Surrealism", "painting" ] }
{ "_id" : 4, "title" : "The Great Wave off Kanagawa", "artists" : "Hokusai",
  "price" : NumberDecimal("167.30"),
  "tags" : [ "woodblock", "ukiyo-e" ] }
{ "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931,
  "price" : NumberDecimal("483.00"),
  "tags" : [ "Surrealism", "painting", "oil" ] }
{ "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913,
  "price" : NumberDecimal("385.00"),
  "tags" : [ "oil", "painting", "abstract" ] }
{ "_id" : 7, "title" : "The Scream", "artist" : "Munch", "year" : 1893,
  "tags" : [ "Expressionism", "painting", "oil" ] }
{ "_id" : 8, "title" : "Blue Flower", "artist" : "O`Keefe", "year" : 1918,
  "price" : NumberDecimal("118.42"),
  "tags" : [ "abstract", "painting" ] }

El siguiente procedimiento aprovecha las funciones de creación de facetas de MongoDB para mostrar a los consumidores el inventario de la tienda organizado por etiquetas, precio y año de generación. Esta etapa $facet comprende tres subcanales que realizan esta agregación multifacética utilizando $sortByCount, $bucket o $bucketAuto..

Los documentos de entrada de artwork solo se recuperan de la base de datos una vez, al inicio de la operación.

Ejemplo:

db.artwork.aggregate( [
  {
    $facet: {
      "categorizedByTags": [
        { $unwind: "$tags" },
        { $sortByCount: "$tags" }
      ],
      "categorizedByPrice": [
        // Filter out documents without a price e.g., _id: 7
        { $match: { price: { $exists: 1 } } },
        {
          $bucket: {
            groupBy: "$price",
            boundaries: [  0, 150, 200, 300, 400 ],
            default: "Other",
            output: {
              "count": { $sum: 1 },
              "titles": { $push: "$title" }
            }
          }
        }
      ],
      "categorizedByYears(Auto)": [
        {
          $bucketAuto: {
            groupBy: "$year",
            buckets: 4
          }
        }
      ]
    }
  }
])

Producción:

$ faceta 1

Artículo relacionado - MongoDB Query