создание веб-страницы nodejs, которая будет извлекать данные из elasticsearch и отображать их в Интернете

#node.js #elasticsearch

Вопрос:

Я впервые в nodejs, поэтому, пожалуйста, окажите некоторую помощь. У меня есть elasticsearch(http://localhost:9200) и кибана(http://localhost:5601) работает на локальном хосте. В эластичном поиске у меня есть посещаемость индекса, к которой я обращаюсь. Я хочу создать api nodejs, который будет извлекать данные с этого сервера elasticsearch и показывать их в браузере. Я использовал приведенный ниже код:

  var http = require('http');
const { Client } = require('@elastic/elasticsearch')
const client = new Client({ node: 'http://localhost:9200' })
var events = require('events');
var url = require('url');

var eventEmitter = new events.EventEmitter();

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.write(req.url);
  eventEmitter.emit(req.url);
  eventEmitter.on('/connection/', connect_new);
  
  res.end();

}).listen(8080);


var connect_new=async function run () {
  await client.search({
    index: 'attendance',
body:{
  "aggs": {
    "3": {
      "terms": {
        "field": "timevar.keyword",
        "order": {
          "_count": "desc"
        },
        "size": 8
      },
      "aggs": {
        "4": {
          "terms": {
            "field": "type.keyword",
            "order": {
              "_count": "desc"
            },
            "size": 5
          }
        }
      }
    }
  },
  "size": 0,
  "fields": [
    {
      "field": "@timestamp",
      "format": "date_time"
    },
    {
      "field": "date",
      "format": "date_time"
    },
    {
      "field": "in_timestamp",
      "format": "date_time"
    }
  ],
  "script_fields": {},
  "stored_fields": [
    "*"
  ],
  "runtime_mappings": {},
  "_source": {
    "excludes": []
  },
  "query": {
    "bool": {
      "must": [],
      "filter": [
        {
          "match_all": {}
        },
        {
          "range": {
            "in_timestamp": {
              "gte": "2021-07-13T07:18:27.397Z",
              "lte": "2021-07-13T08:22:57.064Z",
              "format": "strict_date_optional_time"
            }
          }
        }
      ],
      "should": [],
      "must_not": []
    }
  }
  }}).then(function(resp) {
      //resp.writeHead(200, {'Content-Type': 'text/html'});
    //resp.write('time interval:- '   resp.body.aggregations['3']["buckets"][0]["key"]);
    //resp.write('total students:- '   resp.body.aggregations['3']["buckets"][0]["doc_count"]);
    console.log(resp);
    console.log('time interval:- '   resp.body.aggregations['3']["buckets"][0]["key"]);
    console.log('total students:- '   resp.body.aggregations['3']["buckets"][0]["doc_count"]);
    console.log('time interval:- '   resp.body.aggregations['3']["buckets"][1]["key"]);
    console.log('total students:- '   resp.body.aggregations['3']["buckets"][1]["doc_count"]);
    //res.end();
    }, function(err) {
    console.trace(err.message);
});

}
 

Это обеспечивает мне вывод ниже в командной строке:

 {
  body: {
    took: 4,
    timed_out: false,
    _shards: { total: 1, successful: 1, skipped: 0, failed: 0 },
    hits: { total: [Object], max_score: null, hits: [] },
    aggregations: { '3': [Object] }
  },
  statusCode: 200,
  headers: {
    warning: '299 Elasticsearch-7.13.3-5d21bea28db1e89ecc1f66311ebdec9dc3aa7d64 "Elasticsearch built-in security features are not enabled. Without authentication, your cluster could be accessible to anyone. See https://www.elastic.co/guide/en/elasticsearch/reference/7.13/security-minimal-setup.html to enable security."',
    'content-type': 'application/json; charset=UTF-8',
    'content-length': '827'
  },
  meta: {
    context: null,
    request: { params: [Object], options: {}, id: 2 },
    name: 'elasticsearch-js',
    connection: {
      url: 'http://localhost:9200/',
      id: 'http://localhost:9200/',
      headers: {},
      deadCount: 0,
      resurrectTimeout: 0,
      _openRequests: 0,
      status: 'alive',
      roles: [Object]
    },
    attempts: 0,
    aborted: false
  }
}
time interval:- INTERVAL_01-02
total students:- 54
time interval:- INTERVAL_12-01
total students:- 13
 

Но я хочу, чтобы этот вывод JSON отображался в веб-браузере. где прямо сейчас я получаю только результат ниже:

 /connection/
 

пожалуйста, предложите мне возможное решение. Любое предложение приветствуется.

Комментарии:

1. IANAL, но в лицензии elastic говорится, что вы не можете предоставлять программное обеспечение третьим лицам в качестве размещенной или управляемой службы …

Ответ №1:

Я обнаружил, что мои концепции немного слабы, но после использования промежуточного программного обеспечения все работает так, как ожидалось . И выдача выходных данных в браузер.

 const elasticsearch = require('elasticsearch');
const client = new elasticsearch.Client({hosts: [ 'http://localhost:9200']});
const express = require( 'express' );
const Confirm = require('prompt-confirm');
const app = express();

app.set( 'port', process.env.PORT || 3002 );

app.get('/',check, for_serach,function (req, res){
    let total=req.total_v;
    let values=req.data;
const confirm = new Confirm(total ' Records found.Want to see ?')
  .ask(function(answer) {
    if (answer){
    res.send(values);
    }
    else{
        res.send(total ' Records found.Not showing due to selecting no in prompt');
    }
  });
})

app.get('/delete/',check,for_serach,delete_prompt, function (req, res){

let body =  {
  "size":6500, 
  "query": {
    "range": {
      "in_timestamp": {
        "gte": req.start_date,
        "lte": req.end_date
      }
    }
  }
}

  client.deleteByQuery({index:'attendance',body:body})
  .then(results => {
    res.json(results);
  })
  .catch(err=>{
    console.log(err)
    res.send([]);
  });

})

function delete_prompt(req,res,next){
    let total=req.total_v;
    const confirm = new Confirm(total ' Records found.Confirm for delete :')
  .ask(function(answer) {
    if (answer){
        next()
    }
    else{
    res.send(total ' Records found.Not showing due to selecting no in prompt');
    }
  });
}

function for_serach(req, res,next){
    console.log(req.start_date);
    console.log(req.end_date);
  let body =  {
  "size":6500, 
  "query": {
    "range": {
      "in_timestamp": {
        "gte": req.start_date,
        "lte": req.end_date
      }
    }
  }
}
  client.search({index:'attendance',body:body})
  .then(results => {
     req.total_v= results.hits.total.value; 
     req.data=results.hits.hits;
    next()
  })
  .catch(err=>{
    console.log(err)
    res.send([]);
  });

}

function check(req,res,next){
    let start =req.query.start.toString();
    let end =req.query.end.toString();
    let nstart = start.replace(" ", " ");
    let nend = end.replace(" ", " ");
    let s_date=new Date(nstart);
    let s_end=new Date(nend);
    let c_date=new Date();
    req.start_date=nstart;                      
    req.end_date=nend;
    c_date.setMonth(c_date.getMonth() - 2);
    if(s_date>c_date || s_end>c_date){
        res.send('wrong date:give date prior to 2 month of today');
    }
    else if(s_date>=s_end){
        res.send('End date need to be after start date');
    }
    else
    {   
        next()
    }
}

app .listen( app.get( 'port' ), function(){
  console.log( 'Express server listening on port '   app.get( 'port' ));
} );