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.

Obtén más de 10000 resultados de Elasticsearch con node.js utilizando search_after.

Estoy tratando de obtener más de 10,000 registros de elasticsearch utilizando ‘search_after’. En la documentación oficial se implementa fuera del cuerpo, pero eso me dio un error. Así que hice una búsqueda y descubrí que se debería usar dentro del cuerpo. He intentado implementarlo, pero solo estoy obteniendo 10,000 resultados. Además, no puedo encontrar el id del punto de control en mi respuesta. ¿Alguien puede ayudarme con esto..??

A continuación se muestra mi código:
var client = new elasticsearch.Client({
  host: elasticUrl,
});

const getElasticData = async() => {
    const response = await client.search({
        index: index,
        type: 'doc',
        // size: 10000,
        body: {
          query: {
            match_all: {},
          },
          query: {
            match_all: {},
          },
          sort: [
            {
              "id": {
                "order": "asc"
              }
            }
          ],
          search_after: [10000]
        }
    })
      return response
}

let completeElasticData;

getElasticData().then(res => {
    completeElasticData = res

let displayMsg = completeElasticData ? `Data fetched from elastic: [ ${completeElasticData.hits.total.value} ]` : `something went wrong`

console.log(displayMsg)

app.get('/', (req, res)=>{
    res.send(completeElasticData)
})

}).catch(err => console.log(err));

app.listen(5000, () => console.log('Server started on port 5000'));

###### A continuación se muestra el contenido de package.json

{
“name”: “elasticdata”,
“version”: “1.0.0”,
“description”: “”,
“main”: “index.js”,
“scripts”: {
“start”: “nodemon app.js”
},
“keywords”: [],
“author”: “”,
“license”: “ISC”,
“dependencies”: {
“elasticsearch”: “^16.7.2”,
“express”: “^4.17.2”,
“nodemon”: “^2.0.15”
}
}
“`

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que hay un par de problemas con el código proporcionado.

    En primer lugar, el objeto query en el campo body solo debería especificarse una vez. Tienes query especificado dos veces, lo que podría estar causando problemas.

    En segundo lugar, el parámetro search_after debería ser una matriz que incluya los valores de la última clave de ordenación (en este caso, el campo _id) de la consulta anterior. Entonces, si estás tratando de recuperar más de 10,000 registros, deberías hacer solicitudes posteriores con valores diferentes para el parámetro search_after.

    Aquí tienes una versión actualizada del código que debería funcionar:

    var client = new elasticsearch.Client({
      host: elasticUrl,
    });
    
    let completeElasticData = []; // inicializar con un array vacío
    
    const getElasticData = async(lastId = null) => {
      const response = await client.search({
        index: index,
        type: '_doc',
        body: {
          size: 10000,
          query: { match_all: {} },
          sort: [{ _id: { order: 'asc' } }],
          search_after: lastId ? [lastId] : undefined,
        },
      });
    
      completeElasticData.push(...response.hits.hits); // agregar los "hits" al array
      if (response.hits.total.value > completeElasticData.length) {
        // si aún hay más resultados para recuperar, llamar a la función recursivamente con el último _id como parámetro lastId
        await getElasticData(response.hits.hits[response.hits.hits.length - 1]._id);
      }
    };
    
    getElasticData().then(() => {
      let displayMsg = completeElasticData.length
        ? `Datos recuperados de Elasticsearch: [ ${completeElasticData.length} ]`
        : `algo salió mal`;
    
      console.log(displayMsg);
    
      app.get('/', (req, res) => {
        res.send(completeElasticData);
      });
    });
    
    app.listen(5000, () => console.log('Servidor iniciado en el puerto 5000'));
    

    Este código inicializa un array vacío completeElasticData y luego llama a la función getElasticData con un parámetro opcional lastId que tiene un valor predeterminado de null.

    La función recupera 10,000 registros (o los que queden por recuperar) utilizando el parámetro search_after. Si se pasa lastId como parámetro, se utilizará como el valor de search_after.

    A continuación, se agregan los “hits” a completeElasticData y, si aún hay más registros por recuperar, se llama a la función recursivamente con el último valor _id de los “hits” como parámetro lastId.

    Una vez que se han recuperado todos los registros, el servidor envía los datos completos en respuesta a una solicitud GET.

    ¡Espero que esto ayude!

Comments are closed.