Using Kibana to add data to elasticsearch from forms

I have a couple of things i don't understand.

1 I am trying to create a connection to elasticsearch so that i can access a specific index and then i can add data to it via a form.

my index.js looks like this since i read that you need to create a server and then communicate with elastic search

import exampleRoute from './server/routes/example';

export default function (kibana) {
  return new kibana.Plugin({
    require: ['elasticsearch'],
    name: 'article',
    uiExports: {

      app: {
        title: 'Article',
        description: 'lists articles in Kibana',
        main: 'plugins/article/app'
      },



    },


    init(server, options) {
      // Add server routes and initialize the plugin here
      exampleRoute(server);
      server.route({
        path: '/api/article/index/{name}',
        method: 'GET',
        handler(req, reply) {
          server.plugins.elasticsearch.callWithRequest(req, 'cluster.state', {
            metric: 'metadata',
            index: req.params.name
          }).then(function (response) {
            reply(response.metadata.indices[req.params.name]);
          });
        }
      });
    }


  });
};

then in my app.js i need to know how i would write my controller to access and modify my index in elasticsearch since i dont know what methods are available to help pass form data to elasticsearch.

Before i tried using a different method to access the index and it failed

app.js looked like this

uiModules
.get('app/testcloud', [])
.controller('testcloudHelloWorld', function ($scope, $route, $interval) {
  $scope.title = 'Testcloud';
  $scope.description = 'tags test';


  const currentTime = moment($route.current.locals.currentTime);
  $scope.currentTime = currentTime.format('HH:mm:ss');
  const unsubscribe = $interval(function () {
    $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
  }, 1000);
  $scope.$watch('$destroy', unsubscribe);
});

uiModules
.get('app/testcloud', [])
.controller('dataCtrl', ['$scope','searchService',function($scope, searchService){
  $scope.results = {
    documents: []
  };

  searchService.search().then(function(es_return){
    scope.results.documents = es_return;

    console.log(es_return)
  })



  $scope.title = 'World';
  $scope.description = 'howdy';
  $scope.submit = function() {
    $scope.greeting = 'Hello ' + $scope.title + '!'+ $scope.description +'!';
  };



}]);

uiModules
.get('app/testcloud', [])
.service('searchService', ['$q','esFactory', function($q, esFactory){
  var esClient = esFactory ({
    location: 'localhost:9200'
  });

  this.search = function() {
    var deferred = $q.defer();

    esClient.search({
      index: 'article',
      body: {
        query: {
          match_all:{}
        }
      }
    }).then(function(es_return) {
      deferred.resolve(es_return);
    }, function(error) {
      deferred.reject(error);
    });

    return deferred.promise;
  };
}]);

and my index.html

<div ng-controller="dataCtrl">
  <div class="results">
    <h1>Articles</h1>

    <ul>
      <li ng-repeat="news in results.documents">
        <strong>{{news.title}}</strong>
      </li>
    </ul>

  </div>
  <br>
  Id:
    <input type="text" ng-model="id">
  <br>
  Title:
    <input type="text" ng-model="title">
  <br>
  Description:
    <input type="textarea" ng-model="description">
    <button ng-click='submit()'>submit</button>
 
</div>

Hi @Samuel_Momanyi,

there are two ways to communicate with Elasticsearch from client-side code in Kibana. You can either directly communicate with it from the browser by letting angular inject the es service or create your own server-side api that uses elasticsearch.callWithRequest to write to the database. Both approaches are touched upon in the Kibana Documentation.

I was able to connect to elastic search and i can search data but i am getting a status 404 error

C:\Users\front\Desktop\kibana\node_modules\angular\angular.js:12701 POST http://localhost:5601/api/elasticsearch/article/news/3 404 (Not Found)

when indexing a document

this is my controller

.controller('indexCtrl', function ($scope, es) {

  es.index({
   index: 'article',
   id: '3',
   type: 'news',
   body: {
     "query": {},
     "id": "3",
     "title":"Samuel has done it again",
     "description":"Hello this really cool if it works, please do"
   }

 }).then(function (err,resp,status) {
   if(err) {
      console.log(err);
    }
    else {
      console.log(resp);
    }
   });

});

and this is the server request

server.route({
    path: '/api/genplug/{index}/{type}/{id}',
    method: 'POST',
    handler(req, reply) {
      elasticRequest.callWithRequest(req, 'index', { index: 'article', type: 'news' })
      .then(response =&gt; {
        console.log(`cluster status is: #{response.data}`);
      });
    }
  });

What could I be doing wrong?
[/quote]

As far as I know access to elasticsearch from the Kibana client-side is read-only. Sorry that I did not mention this earlier. So creating a server-side route that does the indexing as shown in your second code snippet is the correct way. In you example I don't see where you call your /api/genplug/... route though. Instead you directly try to write to ES by calling es.index.

I would recommend to use the $http service on the client side to call your server-side route as described in https://www.elastic.co/guide/en/kibana/current/development-basepath.html#_api_requests_from_the_front_end (don't forget to add the basePath like in the example). The request url params and body can convey all information you need to the execute an index operation via callWithRequest, e.g.

elasticRequest.callWithRequest(req, 'index', {
  index: req.params.index,
  id: req.params.id,
  type: req.params.type,
  body: req.payload,
}).then(...)

Just be aware that you're opening write-access to all your data with this route. I would advise to strictly validate the request before using any values from it.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.