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.

Atlas Search funciona demasiado lento al usar la faceta.

Tengo una gran colección (más de 22 millones de registros, aproximadamente 25GB) en un clúster M10 con MongoDB versión 4.4.10. Configuré un índice de búsqueda de Atlas en un campo (dirección) y funciona bastante rápido cuando lo solicito a través del probador de búsqueda. Sin embargo, cuando intento paginarlo especificando una faceta, se vuelve extremadamente lento en comparación con la consulta sin la faceta. ¿Hay alguna forma de optimizar la faceta o reemplazarla de alguna manera por una que funcione más rápido? A continuación se muestran la consulta básica y otra con la faceta:

db.getCollection("users").aggregate([{
    $search: {
        index: 'address',
        text: {
            query: '7148 BIG WOODS DR',
            path: {
                'wildcard': '*'
            }
        }
    }
}]);
db.getCollection("users").aggregate([{
    $search: {
        index: 'address',
        text: {
            query: '7148 BIG WOODS DR',
            path: {
                'wildcard': '*'
            }
        }
    }
}, {
    $facet: {
        paginatedResult: [
            {
                $limit: 50
            },
            {
                $skip: 0
            }
        ],
        totalCount: [
            {
                $count: 'total'
            }
        ]
    }
}]);
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Dado que el tamaño de la colección es enorme, la operación de faceta (que consiste en $skip y $limit) tarda mucho tiempo en ejecutarse, lo que ralentiza considerablemente la consulta. Un enfoque para optimizar la operación de faceta es realizarla en un subconjunto más pequeño de datos (en lugar de la colección completa) que coincida con la consulta de búsqueda.

    Esto se puede lograr agregando una etapa inicial $match antes de la etapa $search en la canalización, que filtra los documentos que no coinciden con la consulta de búsqueda. Por ejemplo:

    db.getCollection("users").aggregate([
      {
        $match: {
          $text: {
            $search: "7148 BIG WOODS DR"
          }
        }
      },
      {
        $search: {
          index: 'address',
          text: {
            query: '7148 BIG WOODS DR',
            path: {
              'wildcard': '*'
            }
          }
        }
      },
      {
        $facet: {
          paginatedResult: [
            {
              $limit: 50
            },
            {
              $skip: 0
            }
          ],
          totalCount: [
            {
              $count: 'total'
            }
          ]
        }
      }
    ]);
    

    En esta consulta modificada, se agrega la etapa $match antes de la etapa $search para filtrar primero los documentos que coinciden con la consulta de búsqueda. De esta manera, la operación de faceta se realizará solo en un subconjunto más pequeño de datos, lo que reduce el tiempo de procesamiento general.

Comments are closed.