Skip to content

Commit

Permalink
added analysis section
Browse files Browse the repository at this point in the history
  • Loading branch information
Leonardo Menezes committed Aug 4, 2016
1 parent e850e2b commit aa50020
Show file tree
Hide file tree
Showing 22 changed files with 1,178 additions and 0 deletions.
48 changes: 48 additions & 0 deletions app/controllers/AnalysisController.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package controllers

import models.analysis.{IndexAnalyzers, IndexFields, OpenIndices, Tokens}
import models.ElasticServer

import scala.concurrent.ExecutionContext.Implicits.global

class AnalysisController extends BaseController {

def getIndices = process { (request, client) =>
client.getIndices(ElasticServer(request.host, request.authentication)).map { response =>
Status(response.status)(OpenIndices(response.body))
}
}

def getIndexAnalyzers = process { (request, client) =>
val index = request.get("index")
client.getIndexSettings(index, ElasticServer(request.host, request.authentication)).map { response =>
Status(response.status)(IndexAnalyzers(index, response.body))
}
}

def getIndexFields = process { (request, client) =>
val index = request.get("index")
client.getIndexMapping(index, ElasticServer(request.host, request.authentication)).map { response =>
Status(response.status)(IndexFields(index, response.body))
}
}

def analyzeByField = process { (request, client) =>
val index = request.get("index")
val field = request.get("field")
val text = request.get("text")
client.analyzeTextByField(index, field, text, ElasticServer(request.host, request.authentication)).map { response =>
Status(response.status)(Tokens(response.body))
}
}

def analyzeByAnalyzer = process { (request, client) =>
val index = request.get("index")
val analyzer = request.get("analyzer")
val text = request.get("text")
client.analyzeTextByAnalyzer(index, analyzer, text, ElasticServer(request.host, request.authentication)).map { response =>
Status(response.status)(Tokens(response.body))
}
}

}
17 changes: 17 additions & 0 deletions app/elastic/ElasticClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,23 @@ trait ElasticClient {
execute(s"${target.host}$path", "POST", Some(metadata.toString), target.authentication)
}

def getIndices(target: ElasticServer) = {
val path = s"/_cat/indices?format=json"
execute(s"${target.host}$path", "GET", None, target.authentication)
}

def analyzeTextByField(index: String, field: String, text: String, target: ElasticServer) = {
val path = s"/$index/_analyze"
val body = Json.obj("text" -> text, "field" -> field).toString()
execute(s"${target.host}$path", "GET", Some(body), target.authentication)
}

def analyzeTextByAnalyzer(index: String, analyzer: String, text: String, target: ElasticServer) = {
val path = s"/$index/_analyze"
val body = Json.obj("text" -> text, "analyzer" -> analyzer).toString()
execute(s"${target.host}$path", "GET", Some(body), target.authentication)
}

def executeRequest(method: String, path: String, data: Option[JsValue], target: ElasticServer) =
execute(s"${target.host}/$path", method, data.map(_.toString), target.authentication)

Expand Down
12 changes: 12 additions & 0 deletions app/models/analysis/IndexAnalyzers.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package models.analysis

import play.api.libs.json._

object IndexAnalyzers {

def apply(index: String, mapping: JsValue): JsArray = {
val analyzers = (mapping \ index \ "settings" \ "index" \ "analysis" \ "analyzer").asOpt[JsObject]
JsArray(analyzers.map(_.keys.toSeq).getOrElse(Seq()).map(JsString(_)))
}

}
40 changes: 40 additions & 0 deletions app/models/analysis/IndexFields.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package models.analysis

import play.api.libs.json._

object IndexFields {

def apply(index: String, data: JsValue) = {
val docTypes = (data \ index \ "mappings").as[JsObject].keys
val fields = docTypes.flatMap { docType =>
extractProperties((data \ index \ "mappings" \ docType \ "properties").as[JsValue])
}.toSeq
JsArray(fields.map(JsString(_)))
}

def extractProperties(data: JsValue): Seq[String] = {
data match {
case obj: JsObject =>
obj.keys.collect {
case p if (data \ p \ "properties").asOpt[JsObject].isDefined =>
extractProperties((data \ p \ "properties").as[JsValue]).map(s"$p.".concat(_))

case p if (data \ p \ "fields").asOpt[JsObject].isDefined =>
val fields = (data \ p \ "fields").as[JsObject].keys.collect {
case field if (data \ p \ "fields" \ field \ "type").asOpt[String].exists(_.equals("string")) =>
s"$p.$field"
}.toSeq
if ((data \ p \ "type").asOpt[String].exists(_.equals("string"))) {
fields :+ p
} else {
fields
}

case p if (data \ p \ "type").asOpt[String].exists(_.equals("string")) =>
Seq(p)
}.flatten.toSeq
case _ => Seq()
}
}

}
11 changes: 11 additions & 0 deletions app/models/analysis/OpenIndices.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package models.analysis

import play.api.libs.json.{JsArray, JsString, JsValue}

object OpenIndices {

def apply(data: JsValue) = JsArray(data.as[JsArray].value.collect {
case index if (index \ "status").as[String].equals("open") => (index \ "index").as[JsString]
})

}
9 changes: 9 additions & 0 deletions app/models/analysis/Tokens.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package models.analysis

import play.api.libs.json.JsValue

object Tokens {

def apply(data: JsValue) = (data \ "tokens").as[JsValue]

}
6 changes: 6 additions & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ POST /apis/get_aliases @controllers.GetAliasesController.e
POST /apis/update_aliases @controllers.UpdateAliasesController.execute
POST /apis/get_index_metadata @controllers.GetIndexMetadataController.execute
POST /apis/create_index @controllers.CreateIndexController.execute
# Analysis module
POST /analysis/indices @controllers.AnalysisController.getIndices
POST /analysis/analyzers @controllers.AnalysisController.getIndexAnalyzers
POST /analysis/fields @controllers.AnalysisController.getIndexFields
POST /analysis/analyze/analyzer @controllers.AnalysisController.analyzeByAnalyzer
POST /analysis/analyze/field @controllers.AnalysisController.analyzeByField

GET /apis/hosts @controllers.HostsController.index

Expand Down
101 changes: 101 additions & 0 deletions public/analysis/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<div class="row">
<div class="col-md-6">
<h4>
analyze by field type
</h4>
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label class="form-label">index name</label>
<select class="form-control" ng-model="fieldAnalysisIndex"
ng-options="index for index in indices | orderBy:index track by index"
ng-change="loadFields(fieldAnalysisIndex)"
>
</select>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label class="form-label">field name</label>
<select class="form-control" ng-model="field"
ng-options="field for field in fields | orderBy:field track by field">
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="form-label">&nbsp;</label>
<input type="text" class="form-control"
placeholder="text to analyze"
ng-model="fieldText">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 text-right">
<button type="submit" class="btn btn-success"
ng-click="analyzeByField(fieldAnalysisIndex, field, fieldText)">
<i class="fa fa-bolt"></i> analyze
</button>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<analysis-tokens tokens="field_tokens"></analysis-tokens>
</div>
</div>
</div>
<div class="col-md-6">
<h4>
analyze by analyzer
</h4>
<div class="row">
<div class="col-sm-4">
<div class="form-group">
<label class="form-label">index name</label>
<select class="form-control"
ng-model="analyzerAnalysisIndex"
ng-options="index for index in indices | orderBy:index track by index"
ng-change="loadAnalyzers(analyzerAnalysisIndex)"
>
</select>
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label class="form-label">analyzer name</label>
<select class="form-control"
ng-model="analyzer"
ng-options="analyzer for analyzer in analyzers | orderBy:analyzer track by analyzer">
</select>
</div>
</div>
<div class="col-sm-4"></div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<label class="form-label">&nbsp;</label>
<input type="text" class="form-control"
placeholder="text to analyze"
ng-model="analyzerText">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12 text-right">
<button type="submit" class="btn btn-success"
ng-click="analyzeByAnalyzer(analyzerAnalysisIndex, analyzer, analyzerText)">
<i class="fa fa-bolt"></i> analyze
</button>
</div>
</div>
<div class="row">
<div class="col-lg-12">
<analysis-tokens tokens="analyzer_tokens"></analysis-tokens>
</div>
</div>
</div>
</div>
16 changes: 16 additions & 0 deletions public/analysis/tokens.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<table class="table" ng-show="tokens">
<thead>
<tr>
<th>token</th>
<th>position</th>
<th>start offset</th>
<th>end offset</th>
</tr>
</thead>
<tr ng-repeat="token in tokens track by $index">
<td>{{token.token}}</td>
<td>{{token.position}}</td>
<td>{{token.start_offset}}</td>
<td>{{token.end_offset}}</td>
</tr>
</table>
Loading

0 comments on commit aa50020

Please sign in to comment.