Para poder comunicar R con ElasticSearch existen en este momento varias librerías que resuelven muchos de los usos habituales (elasticsearchr, elastic).
El poder de ElasticSearch como herramienta de consulta es extremadamente alto gracias a sus numerosas cualidades.
El problema que hoy se encuentra quien quiera aprovechar todo el potencial de ElasticSearch desde R es que las librerías existentes no proveen funciones versátiles respecto al tipo de consulta que uno desee realizar.
Las consultas de tipos más complejas no encuentran manera de ser ejecutadas por las funciones que proveen las librerías citadas.
El objetivo con mi función Consulta_ElasticSearch es que pueda resolverse cualquier tipo de consulta.
La función puede obtenerse fácilmente desde el siguiente Link. Luego de descargar el archivo .rds, crear la función es muy fácil:
readRDS("Consulta_ElasticSearch.rds")->Consulta_ElasticSearch
Para los que no conozcan mucho respecto a esta herramienta, les dejo un link con un poco más de información: https://es.wikipedia.org/wiki/Elasticsearch
En este pequeño tutorial se utilizaran diferentes ejemplos de querys. Para quien desee conocer un poco más al respecto pueden hacerlo a través de este link: Introducing the Query Language
Para conocer un poco más sobre los alcances de estas librerías pueden seguir los siguientes links:
elasticsearchr: a Lightweight Elasticsearch Client for R
Utilizamos el dataset diamonds del paquete ggplot2:
ggplot2::diamonds->diamonds
diamonds
## # A tibble: 53,940 x 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
## 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
## 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
## 4 0.290 Premium I VS2 62.4 58 334 4.2 4.23 2.63
## 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
## 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
## 7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
## 8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53
## 9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49
## 10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39
## # ... with 53,930 more rows
Indexamos el dataset a traves de la función %index% del paquete “elasticsearchr”:
library("elasticsearchr")
elastic("http://localhost:9200", "diamonds", "data") %index% diamonds
La función busca generar un entorno flexible para correr cualquier tipo de consulta sin importar si el resultado pueda convertirse en un data.frame. (Posiblemente el pecado de las otras librerías es intentar forzar siempre el resultado a la estructura de un data.frame)
'{
"size":2,
"query": {
"match_all": {}
}
}' %>%
Consulta_ElasticSearch("diamonds")->rdos
str(rdos)
## List of 4
## $ took : int 0
## $ timed_out: logi FALSE
## $ _shards :List of 4
## ..$ total : int 1
## ..$ successful: int 1
## ..$ skipped : int 0
## ..$ failed : int 0
## $ hits :List of 3
## ..$ total :List of 2
## .. ..$ value : int 10000
## .. ..$ relation: chr "gte"
## ..$ max_score: num 1
## ..$ hits :List of 2
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "Ykl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.23
## .. .. .. ..$ cut : chr "Ideal"
## .. .. .. ..$ color : chr "E"
## .. .. .. ..$ clarity: chr "SI2"
## .. .. .. ..$ depth : num 61.5
## .. .. .. ..$ table : num 55
## .. .. .. ..$ price : int 326
## .. .. .. ..$ x : num 3.95
## .. .. .. ..$ y : num 3.98
## .. .. .. ..$ z : num 2.43
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "Y0l__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.21
## .. .. .. ..$ cut : chr "Premium"
## .. .. .. ..$ color : chr "E"
## .. .. .. ..$ clarity: chr "SI1"
## .. .. .. ..$ depth : num 59.8
## .. .. .. ..$ table : num 61
## .. .. .. ..$ price : int 326
## .. .. .. ..$ x : num 3.89
## .. .. .. ..$ y : num 3.84
## .. .. .. ..$ z : num 2.31
'{
"size" : 1,
"_source":["cut","clarity"],
"query" : {
"term" : { "cut" : "good" }
}
}' %>% Consulta_ElasticSearch("diamonds")->rdos
str(rdos)
## List of 4
## $ took : int 1
## $ timed_out: logi FALSE
## $ _shards :List of 4
## ..$ total : int 1
## ..$ successful: int 1
## ..$ skipped : int 0
## ..$ failed : int 0
## $ hits :List of 3
## ..$ total :List of 2
## .. ..$ value : int 10000
## .. ..$ relation: chr "gte"
## ..$ max_score: num 1.25
## ..$ hits :List of 1
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "ZEl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1.25
## .. .. ..$ _source:List of 2
## .. .. .. ..$ cut : chr "Good"
## .. .. .. ..$ clarity: chr "VS1"
'{ "aggs" : {
"my_buckets": {
"composite" : {
"size": 10,
"sources" : [
{ "Var1": { "terms": {"field": "cut.keyword" } } },
{ "Var2": { "terms": {"field": "color.keyword" } } }
]
}
}}}' %>% Consulta_ElasticSearch("diamonds")->rdos
str(rdos)
## List of 5
## $ took : int 2
## $ timed_out : logi FALSE
## $ _shards :List of 4
## ..$ total : int 1
## ..$ successful: int 1
## ..$ skipped : int 0
## ..$ failed : int 0
## $ hits :List of 3
## ..$ total :List of 2
## .. ..$ value : int 10000
## .. ..$ relation: chr "gte"
## ..$ max_score: num 1
## ..$ hits :List of 10
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "Ykl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.23
## .. .. .. ..$ cut : chr "Ideal"
## .. .. .. ..$ color : chr "E"
## .. .. .. ..$ clarity: chr "SI2"
## .. .. .. ..$ depth : num 61.5
## .. .. .. ..$ table : num 55
## .. .. .. ..$ price : int 326
## .. .. .. ..$ x : num 3.95
## .. .. .. ..$ y : num 3.98
## .. .. .. ..$ z : num 2.43
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "Y0l__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.21
## .. .. .. ..$ cut : chr "Premium"
## .. .. .. ..$ color : chr "E"
## .. .. .. ..$ clarity: chr "SI1"
## .. .. .. ..$ depth : num 59.8
## .. .. .. ..$ table : num 61
## .. .. .. ..$ price : int 326
## .. .. .. ..$ x : num 3.89
## .. .. .. ..$ y : num 3.84
## .. .. .. ..$ z : num 2.31
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "ZEl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.23
## .. .. .. ..$ cut : chr "Good"
## .. .. .. ..$ color : chr "E"
## .. .. .. ..$ clarity: chr "VS1"
## .. .. .. ..$ depth : num 56.9
## .. .. .. ..$ table : num 65
## .. .. .. ..$ price : int 327
## .. .. .. ..$ x : num 4.05
## .. .. .. ..$ y : num 4.07
## .. .. .. ..$ z : num 2.31
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "ZUl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.29
## .. .. .. ..$ cut : chr "Premium"
## .. .. .. ..$ color : chr "I"
## .. .. .. ..$ clarity: chr "VS2"
## .. .. .. ..$ depth : num 62.4
## .. .. .. ..$ table : num 58
## .. .. .. ..$ price : int 334
## .. .. .. ..$ x : num 4.2
## .. .. .. ..$ y : num 4.23
## .. .. .. ..$ z : num 2.63
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "Zkl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.31
## .. .. .. ..$ cut : chr "Good"
## .. .. .. ..$ color : chr "J"
## .. .. .. ..$ clarity: chr "SI2"
## .. .. .. ..$ depth : num 63.3
## .. .. .. ..$ table : num 58
## .. .. .. ..$ price : int 335
## .. .. .. ..$ x : num 4.34
## .. .. .. ..$ y : num 4.35
## .. .. .. ..$ z : num 2.75
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "Z0l__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.24
## .. .. .. ..$ cut : chr "Very Good"
## .. .. .. ..$ color : chr "J"
## .. .. .. ..$ clarity: chr "VVS2"
## .. .. .. ..$ depth : num 62.8
## .. .. .. ..$ table : num 57
## .. .. .. ..$ price : int 336
## .. .. .. ..$ x : num 3.94
## .. .. .. ..$ y : num 3.96
## .. .. .. ..$ z : num 2.48
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "aEl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.24
## .. .. .. ..$ cut : chr "Very Good"
## .. .. .. ..$ color : chr "I"
## .. .. .. ..$ clarity: chr "VVS1"
## .. .. .. ..$ depth : num 62.3
## .. .. .. ..$ table : num 57
## .. .. .. ..$ price : int 336
## .. .. .. ..$ x : num 3.95
## .. .. .. ..$ y : num 3.98
## .. .. .. ..$ z : num 2.47
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "aUl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.26
## .. .. .. ..$ cut : chr "Very Good"
## .. .. .. ..$ color : chr "H"
## .. .. .. ..$ clarity: chr "SI1"
## .. .. .. ..$ depth : num 61.9
## .. .. .. ..$ table : num 55
## .. .. .. ..$ price : int 337
## .. .. .. ..$ x : num 4.07
## .. .. .. ..$ y : num 4.11
## .. .. .. ..$ z : num 2.53
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "akl__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.22
## .. .. .. ..$ cut : chr "Fair"
## .. .. .. ..$ color : chr "E"
## .. .. .. ..$ clarity: chr "VS2"
## .. .. .. ..$ depth : num 65.1
## .. .. .. ..$ table : num 61
## .. .. .. ..$ price : int 337
## .. .. .. ..$ x : num 3.87
## .. .. .. ..$ y : num 3.78
## .. .. .. ..$ z : num 2.49
## .. ..$ :List of 5
## .. .. ..$ _index : chr "diamonds"
## .. .. ..$ _type : chr "data"
## .. .. ..$ _id : chr "a0l__GwBUv9pzHDMjD3U"
## .. .. ..$ _score : num 1
## .. .. ..$ _source:List of 10
## .. .. .. ..$ carat : num 0.23
## .. .. .. ..$ cut : chr "Very Good"
## .. .. .. ..$ color : chr "H"
## .. .. .. ..$ clarity: chr "VS1"
## .. .. .. ..$ depth : num 59.4
## .. .. .. ..$ table : num 61
## .. .. .. ..$ price : int 338
## .. .. .. ..$ x : num 4
## .. .. .. ..$ y : num 4.05
## .. .. .. ..$ z : num 2.39
## $ aggregations:List of 1
## ..$ my_buckets:List of 2
## .. ..$ after_key:List of 2
## .. .. ..$ Var1: chr "Good"
## .. .. ..$ Var2: chr "F"
## .. ..$ buckets :List of 10
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Fair"
## .. .. .. .. ..$ Var2: chr "D"
## .. .. .. ..$ doc_count: int 163
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Fair"
## .. .. .. .. ..$ Var2: chr "E"
## .. .. .. ..$ doc_count: int 224
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Fair"
## .. .. .. .. ..$ Var2: chr "F"
## .. .. .. ..$ doc_count: int 312
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Fair"
## .. .. .. .. ..$ Var2: chr "G"
## .. .. .. ..$ doc_count: int 314
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Fair"
## .. .. .. .. ..$ Var2: chr "H"
## .. .. .. ..$ doc_count: int 303
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Fair"
## .. .. .. .. ..$ Var2: chr "I"
## .. .. .. ..$ doc_count: int 175
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Fair"
## .. .. .. .. ..$ Var2: chr "J"
## .. .. .. ..$ doc_count: int 119
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Good"
## .. .. .. .. ..$ Var2: chr "D"
## .. .. .. ..$ doc_count: int 662
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Good"
## .. .. .. .. ..$ Var2: chr "E"
## .. .. .. ..$ doc_count: int 933
## .. .. ..$ :List of 2
## .. .. .. ..$ key :List of 2
## .. .. .. .. ..$ Var1: chr "Good"
## .. .. .. .. ..$ Var2: chr "F"
## .. .. .. ..$ doc_count: int 909
A continuación el código completo para crear la función:
Consulta_ElasticSearch<-function(consulta=NULL,
indice=NULL,
tipo="_search",
url="http://localhost:9200") {
require(httr)
donde<-paste(url,indice,tipo,sep="/")
content(POST(
donde,
body = consulta,
content_type("application/json")
))
}