From e2a0482fcbe3766cc25162238e14badd1c3fa756 Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 11:15:48 -0600 Subject: [PATCH 01/22] Prototype of an aggs parser handle --- NAMESPACE | 1 + R/aggs.R | 42 ++++++++++++++++++++++++++++++++++++++++++ man/aggs.Rd | 31 +++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 R/aggs.R create mode 100644 man/aggs.Rd diff --git a/NAMESPACE b/NAMESPACE index d9804c4..8503c63 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,6 +8,7 @@ S3method(as.query,range) S3method(print,index) export("%>%") export(Search_) +export(aggs) export(and) export(bool) export(bool_) diff --git a/R/aggs.R b/R/aggs.R new file mode 100644 index 0000000..9646b0e --- /dev/null +++ b/R/aggs.R @@ -0,0 +1,42 @@ +#' elastic DSL aggs +#' +#' @name aggs +#' +#' @param .obj An index object. If nothing passed defaults to all indices, equivalent to +#' doing e.g., \code{localhost:9200/_search} +#' @param ... Further args passed on +NULL + +#' Aggregations +#' +#' @export +#' @rdname aggs +#' +#' +#' @examples +#' target <- Search( +#' index = "gbif", +#' body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) +#' +#' aggs_example <- index("gbif") %>% +#' aggs(x = list(statistic = list(avg = list(field = "decimalLatitude")))) +#' +#' identical(target$aggregations, aggs_example$aggregations) +#' +aggs <- function(.obj = list(), ...) { + aggs_(.obj, .dots = lazyeval::lazy_dots(...)) +} + +aggs_ <- function(.obj=list(), ..., .dots) { + dots <- lazyeval::all_dots(.dots, ...) + + as.json.aggs <- function(x, ...) { + jsonlite::toJSON(list(aggs = x), ..., auto_unbox = TRUE) + } + + query <- as.json.aggs(structure(lazy_eval(dots$x), class=c("aggs", "lazy_dots", "list"))) + execute <- function(.obj, query){ + Search_(.obj, body = query) + } + execute(.obj, query) +} diff --git a/man/aggs.Rd b/man/aggs.Rd new file mode 100644 index 0000000..57ba400 --- /dev/null +++ b/man/aggs.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/aggs.R +\name{aggs} +\alias{aggs} +\title{elastic DSL aggs} +\usage{ +aggs(.obj = list(), ...) +} +\arguments{ +\item{.obj}{An index object. If nothing passed defaults to all indices, equivalent to +doing e.g., \code{localhost:9200/_search}} + +\item{...}{Further args passed on} +} +\description{ +elastic DSL aggs + +Aggregations +} +\examples{ +target <- Search( +index = "gbif", +body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) + +aggs_example <- index("gbif") \%>\% + aggs(x = list(statistic = list(avg = list(field = "decimalLatitude")))) + +identical(target$aggregations, aggs_example$aggregations) + +} + From 3b7be5f5e3b4826d2e3be9e7ac7f705fad1ee977 Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 11:25:09 -0600 Subject: [PATCH 02/22] Remove duplicate function --- R/zzz.r | 2 -- 1 file changed, 2 deletions(-) diff --git a/R/zzz.r b/R/zzz.r index 2fdc91c..73feb79 100644 --- a/R/zzz.r +++ b/R/zzz.r @@ -1,7 +1,5 @@ ec <- function (l) Filter(Negate(is.null), l) -ec <- function (l) Filter(Negate(is.null), l) - cl <- function(x) if(is.null(x)) NULL else paste0(x, collapse = ",") pluck <- function(x, name, type) { From 66e43f42a1a8519bd41e9023ad76268407da436f Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 11:33:18 -0600 Subject: [PATCH 03/22] Help CI know where the Search function comes from --- R/aggs.R | 1 + man/aggs.Rd | 1 + 2 files changed, 2 insertions(+) diff --git a/R/aggs.R b/R/aggs.R index 9646b0e..2aac905 100644 --- a/R/aggs.R +++ b/R/aggs.R @@ -14,6 +14,7 @@ NULL #' #' #' @examples +#' library(elastic) #' target <- Search( #' index = "gbif", #' body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) diff --git a/man/aggs.Rd b/man/aggs.Rd index 57ba400..db1ae6c 100644 --- a/man/aggs.Rd +++ b/man/aggs.Rd @@ -18,6 +18,7 @@ elastic DSL aggs Aggregations } \examples{ +library(elastic) target <- Search( index = "gbif", body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) From 5c00cc327c6d78b7e9d86fb9d7dff012178493e5 Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 20:15:10 -0600 Subject: [PATCH 04/22] Remove example that causes CI to fail --- R/aggs.R | 12 ------------ man/aggs.Rd | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/R/aggs.R b/R/aggs.R index 2aac905..25ea9a6 100644 --- a/R/aggs.R +++ b/R/aggs.R @@ -12,18 +12,6 @@ NULL #' @export #' @rdname aggs #' -#' -#' @examples -#' library(elastic) -#' target <- Search( -#' index = "gbif", -#' body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) -#' -#' aggs_example <- index("gbif") %>% -#' aggs(x = list(statistic = list(avg = list(field = "decimalLatitude")))) -#' -#' identical(target$aggregations, aggs_example$aggregations) -#' aggs <- function(.obj = list(), ...) { aggs_(.obj, .dots = lazyeval::lazy_dots(...)) } diff --git a/man/aggs.Rd b/man/aggs.Rd index db1ae6c..845ed35 100644 --- a/man/aggs.Rd +++ b/man/aggs.Rd @@ -17,16 +17,4 @@ elastic DSL aggs Aggregations } -\examples{ -library(elastic) -target <- Search( -index = "gbif", -body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) - -aggs_example <- index("gbif") \%>\% - aggs(x = list(statistic = list(avg = list(field = "decimalLatitude")))) - -identical(target$aggregations, aggs_example$aggregations) - -} From 4d48308c526b70dce083798715fef5cedc365326 Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 21:59:28 -0600 Subject: [PATCH 05/22] Add first tests --- DESCRIPTION | 3 ++- tests/testthat.R | 5 +++++ tests/testthat/test-filter.R | 7 +++++++ tests/testthat/test-index.R | 12 ++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/testthat.R create mode 100644 tests/testthat/test-filter.R create mode 100644 tests/testthat/test-index.R diff --git a/DESCRIPTION b/DESCRIPTION index 9f3337a..2421745 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -17,4 +17,5 @@ Imports: dplyr Suggests: roxygen2, - knitr + knitr, + testthat diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..d6df141 --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,5 @@ +library(testthat) +library(elasticdsl) + +test_check("elasticdsl") +connect(paste0("http://", Sys.getenv("ES_IP"))) diff --git a/tests/testthat/test-filter.R b/tests/testthat/test-filter.R new file mode 100644 index 0000000..e008790 --- /dev/null +++ b/tests/testthat/test-filter.R @@ -0,0 +1,7 @@ +context("filter.R") + + +test_that("functions return the correct classes", { + expect_true("filtered" %in% class(filter(NULL))) +}) + diff --git a/tests/testthat/test-index.R b/tests/testthat/test-index.R new file mode 100644 index 0000000..e83e25b --- /dev/null +++ b/tests/testthat/test-index.R @@ -0,0 +1,12 @@ +context("index.R") + + +test_that("index() returns the right class", { + # Using the ES_IP env var to pass in the + # cluster's ip. + expect_equal(class(index("gbif")), "index") +}) + +test_that("indices returns at least one index", { + expect_gt(length(indices()), 0) +}) From 9ae2125518587109a38a85e41c76b728885c38ac Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Mon, 29 Feb 2016 10:56:01 -0600 Subject: [PATCH 06/22] Connect to Elasticsearch prior to running tests --- tests/test-all.R | 22 ++++++++++++++++++++++ tests/testthat.R | 5 ----- 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 tests/test-all.R delete mode 100644 tests/testthat.R diff --git a/tests/test-all.R b/tests/test-all.R new file mode 100644 index 0000000..2ee8c54 --- /dev/null +++ b/tests/test-all.R @@ -0,0 +1,22 @@ +library('testthat') +library('elasticdsl') + +if(Sys.getenv("ES_IP") != "") { + # The ES_IP environmental var can be set the root ip of the + # Elasticsearch for convenience. Continuous integration uses + # the default localhost address. + # + # If developing with docker, it is possible to forward the VM's ip + # to localhost using a reverse proxy server like nginx. + # https://forums.docker.com/t/using-localhost-for-to-access-running-container/3148/6 + invisible(elastic::connect(Sys.getenv("ES_IP"))) +} else { + invisible(elastic::connect()) +} + +shakespeare <- system.file("examples", "shakespeare_data.json", package = "elastic") +invisible(elastic::docs_bulk(shakespeare)) +gbif <- system.file("examples", "gbif_data.json", package = "elastic") +invisible(elastic::docs_bulk(gbif)) + +test_check("elasticdsl") diff --git a/tests/testthat.R b/tests/testthat.R deleted file mode 100644 index d6df141..0000000 --- a/tests/testthat.R +++ /dev/null @@ -1,5 +0,0 @@ -library(testthat) -library(elasticdsl) - -test_check("elasticdsl") -connect(paste0("http://", Sys.getenv("ES_IP"))) From f7f39b2246a8357eb215e86d3a861aa8db362f48 Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Mon, 29 Feb 2016 10:23:45 -0800 Subject: [PATCH 07/22] udpate travis file to install/start elasticsearch --- .travis.yml | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ab4a2e9..ddc05bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,57 @@ language: r -sudo: required +env: + matrix: + - ES_VERSION=1.0.0 + - ES_VERSION=1.4.0 + - ES_VERSION=1.7.2 + - ES_VERSION=2.0.0 + - ES_VERSION=2.1.0 + - ES_VERSION=2.2.0 + +before_install: + - case "$ES_VERSION" in + "") ;; + + "1.0.0") + export ES_VERSION=1.0.0 ; + curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-$ES_VERSION.deb && sudo dpkg -i --force-confnew elasticsearch-$ES_VERSION.deb && sudo service elasticsearch start + ;; + + "1.4.0") + export ES_VERSION=1.4.0 ; + curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-$ES_VERSION.deb && sudo dpkg -i --force-confnew elasticsearch-$ES_VERSION.deb && sudo service elasticsearch start + ;; + + "1.7.2") + export ES_VERSION=1.7.2 ; + curl -O https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-$ES_VERSION.deb && sudo dpkg -i --force-confnew elasticsearch-$ES_VERSION.deb && sudo service elasticsearch start + ;; + + "2.0.0") + export ES_VERSION=2.0.0 ; + curl -O https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/$ES_VERSION/elasticsearch-$ES_VERSION.deb && sudo dpkg -i --force-confnew elasticsearch-$ES_VERSION.deb && sudo service elasticsearch start + ;; + + "2.1.0") + export ES_VERSION=2.1.0 ; + curl -O https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/$ES_VERSION/elasticsearch-$ES_VERSION.deb && sudo dpkg -i --force-confnew elasticsearch-$ES_VERSION.deb && sudo service elasticsearch start + ;; + + "2.2.0") + export ES_VERSION=2.2.0 ; + curl -O https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/$ES_VERSION/elasticsearch-$ES_VERSION.deb && sudo dpkg -i --force-confnew elasticsearch-$ES_VERSION.deb && sudo service elasticsearch start + ;; + esac + + - sleep 3 + - sudo service elasticsearch status + +r_packages: +- covr + +after_success: +- Rscript -e 'covr::codecov()' notifications: email: From b42917f2dca33c150c65d6d2eaf735a78dff2f97 Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Mon, 29 Feb 2016 10:58:04 -0800 Subject: [PATCH 08/22] rbuildignore .deb files on elasticsearch install on travis --- .Rbuildignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.Rbuildignore b/.Rbuildignore index 03b11c6..94743c7 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,3 +7,5 @@ appveyor.yml ^Makefile$ man-roxygen ^CONDUCT\.md$ +\.deb$ + From bc61c49f062825e5647d6e675a5617603cd34b8d Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Tue, 1 Mar 2016 16:26:20 -0800 Subject: [PATCH 09/22] using newer last pipe helpers from jqr, #6 put old piper in inst/ignore --- R/pipers.R | 72 ++++++++++++++++----------------- inst/ignore/pipers_old.R | 86 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 36 deletions(-) create mode 100644 inst/ignore/pipers_old.R diff --git a/R/pipers.R b/R/pipers.R index 340b0d0..1593e02 100644 --- a/R/pipers.R +++ b/R/pipers.R @@ -1,9 +1,34 @@ # from @smbache Stefan Milton Bache +#' Information on Potential Pipeline +#' +#' This function figures out whether it is called from within a pipeline. +#' It does so by examining the parent evironment of the active system frames, +#' and whether any of these are the same as the enclosing environment of +#' \code{\%>\%}. +#' +#' @return A list with the values \code{is_piped} (logical) and \code{env} +#' (an environment reference). The former is \code{TRUE} if a pipeline is +#' identified as \code{FALSE} otherwise. The latter holds a reference to +#' the \code{\%>\%} frame where the pipeline is created and evaluated. +#' +#' @noRd +pipeline_info <- function() { + parents <- lapply(sys.frames(), parent.env) + + is_magrittr_env <- + vapply(parents, identical, logical(1), y = environment(`%>%`)) + + is_piped <- any(is_magrittr_env) + + list(is_piped = is_piped, + env = if (is_piped) sys.frames()[[max(which(is_magrittr_env))]]) +} + #' Toggle Auto Execution On or Off for Pipelines #' #' A call to \code{pipe_autoexec} allows a function to toggle auto execution of -#' \code{http} on or off at the end of a pipeline. +#' \code{jq} on or off at the end of a pipeline. #' #' @param toggle logical: \code{TRUE} toggles auto execution on, \code{FALSE} #' toggles auto execution off. @@ -14,7 +39,7 @@ #' changed to \code{identity}. #' #' @noRd -pipe_autoexec <- function(toggle, method = "GET") { +pipe_autoexec <- function(toggle) { if (!identical(toggle, TRUE) && !identical(toggle, FALSE)) { stop("Argument 'toggle' must be logical.") } @@ -22,44 +47,20 @@ pipe_autoexec <- function(toggle, method = "GET") { info <- pipeline_info() if (isTRUE(info[["is_piped"]])) { + es_exit <- function(j) if (inherits(j, "esdsl")) exec2(j) else j pipeline_on_exit(info$env) - info$env$.exec_exitfun <- if (toggle) exec else identity + info$env$.es_exitfun <- if (toggle) es_exit else identity } invisible() } -#' Information on Potential Pipeline -#' -#' This function figures out whether it is called from within a pipeline. -#' It does so by examining the parent evironment of the active system frames, -#' and whether any of these are the same as the enclosing environment of -#' \code{\%>\%}. -#' -#' @return A list with the values \code{is_piped} (logical) and \code{env} -#' (an environment reference). The former is \code{TRUE} if a pipeline is -#' identified as \code{FALSE} otherwise. The latter holds a reference to -#' the \code{\%>\%} frame where the pipeline is created and evaluated. -#' -#' @noRd -pipeline_info <- function() { - parents <- lapply(sys.frames(), parent.env) - - is_magrittr_env <- - vapply(parents, identical, logical(1), y = environment(`%>%`)) - - is_piped <- any(is_magrittr_env) - - list(is_piped = is_piped, - env = if (is_piped) sys.frames()[[min(which(is_magrittr_env))]]) -} - #' Setup On-Exit Action for a Pipeline #' #' A call to \code{pipeline_on_exit} will setup the pipeline for auto execution by #' making \code{result} inside \code{\%>\%} an active binding. The initial #' call will register the \code{identity} function as the exit action, -#' but this can be changed to \code{jq} with a call to \code{pipe_autoexec}. +#' but this can be changed to \code{exec} with a call to \code{pipe_autoexec}. #' Subsequent calls to \code{pipeline_on_exit} has no effect. #' #' @param env A reference to the \code{\%>\%} environment, in which @@ -68,21 +69,20 @@ pipeline_info <- function() { #' @noRd pipeline_on_exit <- function(env) { # Only activate the first time; after this the binding is already active. - if (exists(".exec_exitfun", envir = env, inherits = FALSE, mode = "function")) { + if (exists(".es_exitfun", envir = env, inherits = FALSE, mode = "function")) { return(invisible()) } - env$.exec_exitfun <- identity + env$.es_exitfun <- identity res <- NULL - exec_result <- function(v) { + es_result <- function(v) { if (missing(v)) { res - } - else { - res <<- `$<-`(v, value, env$.exec_exitfun(v$value)) + } else { + res <<- `$<-`(v, value, env$.es_exitfun(v$value)) } } - makeActiveBinding("result", exec_result, env) + makeActiveBinding("result", es_result, env) } diff --git a/inst/ignore/pipers_old.R b/inst/ignore/pipers_old.R new file mode 100644 index 0000000..8bef0e0 --- /dev/null +++ b/inst/ignore/pipers_old.R @@ -0,0 +1,86 @@ +#' Toggle Auto Execution On or Off for Pipelines +#' +#' A call to \code{pipe_autoexec} allows a function to toggle auto execution of +#' \code{http} on or off at the end of a pipeline. +#' +#' @param toggle logical: \code{TRUE} toggles auto execution on, \code{FALSE} +#' toggles auto execution off. +#' +#' @details Once auto execution is turned on the \code{result} identifier inside +#' the pipeline is bound to an "Active Binding". This will not be changed on +#' toggling auto execution off, but rather the function to be executed is +#' changed to \code{identity}. +#' +#' @noRd +pipe_autoexec <- function(toggle, method = "GET") { + if (!identical(toggle, TRUE) && !identical(toggle, FALSE)) { + stop("Argument 'toggle' must be logical.") + } + + info <- pipeline_info() + + if (isTRUE(info[["is_piped"]])) { + pipeline_on_exit(info$env) + info$env$.exec_exitfun <- if (toggle) exec else identity + } + + invisible() +} + +#' Information on Potential Pipeline +#' +#' This function figures out whether it is called from within a pipeline. +#' It does so by examining the parent evironment of the active system frames, +#' and whether any of these are the same as the enclosing environment of +#' \code{\%>\%}. +#' +#' @return A list with the values \code{is_piped} (logical) and \code{env} +#' (an environment reference). The former is \code{TRUE} if a pipeline is +#' identified as \code{FALSE} otherwise. The latter holds a reference to +#' the \code{\%>\%} frame where the pipeline is created and evaluated. +#' +#' @noRd +pipeline_info <- function() { + parents <- lapply(sys.frames(), parent.env) + + is_magrittr_env <- + vapply(parents, identical, logical(1), y = environment(`%>%`)) + + is_piped <- any(is_magrittr_env) + + list(is_piped = is_piped, + env = if (is_piped) sys.frames()[[min(which(is_magrittr_env))]]) +} + +#' Setup On-Exit Action for a Pipeline +#' +#' A call to \code{pipeline_on_exit} will setup the pipeline for auto execution by +#' making \code{result} inside \code{\%>\%} an active binding. The initial +#' call will register the \code{identity} function as the exit action, +#' but this can be changed to \code{jq} with a call to \code{pipe_autoexec}. +#' Subsequent calls to \code{pipeline_on_exit} has no effect. +#' +#' @param env A reference to the \code{\%>\%} environment, in which +#' \code{result} is to be bound. +#' +#' @noRd +pipeline_on_exit <- function(env) { + # Only activate the first time; after this the binding is already active. + if (exists(".exec_exitfun", envir = env, inherits = FALSE, mode = "function")) { + return(invisible()) + } + env$.exec_exitfun <- identity + + res <- NULL + + exec_result <- function(v) { + if (missing(v)) { + res + } + else { + res <<- `$<-`(v, value, env$.exec_exitfun(v$value)) + } + } + + makeActiveBinding("result", exec_result, env) +} From 23d431be53e61c88f3da1f5c1d94687efd19f809 Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Tue, 1 Mar 2016 16:27:23 -0800 Subject: [PATCH 10/22] added describe fxn to explain query, #12 works for some, but likely will need more work to work in all cases --- R/describe.R | 45 +++++++++++++++++++++++++++++++++++++++++++++ man/describe.Rd | 27 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 R/describe.R create mode 100644 man/describe.Rd diff --git a/R/describe.R b/R/describe.R new file mode 100644 index 0000000..f46b0a3 --- /dev/null +++ b/R/describe.R @@ -0,0 +1,45 @@ +#' Explain a query +#' +#' @export +#' @param .data (list) input, using higher level interface +#' @examples +#' index("shakespeare") %>% range( speech_number <= 5 ) %>% describe +#' +#' index("shakespeare") %>% +#' bool(must_not = list(term=list(speaker="KING HENRY IV"))) %>% +#' describe +#' +#' index("geoshape") %>% +#' geoshape(field = "location", type = "envelope", +#' coordinates = list(c(-30, 50), c(30, 0))) %>% +#' describe() +describe <- function(.data) { + pipe_autoexec(toggle = FALSE) + if (!inherits(.data, "esdsl")) stop("must be of class esdsl", call. = FALSE) + structure(make_query(.data), class = "elasticdsl_query") +} + +#' @export +print.elasticdsl_query <- function(x, ...) { + cat("", sep = "\n") + cat(paste0(" base: ", x$url), sep = "\n") + cat(paste0(" index: ", x$index), sep = "\n") + cat(paste0(" query: \n", x$query), sep = "\n") +} + +make_query <- function(x) { + list( + url = es_make_url(elastic::connection()), + index = attr(x$index, "index"), + query = jsonlite::prettify(x$query) + ) +} + +es_make_url <- function(x) { + if (is.null(x$port) || nchar(x$port) == 0) { + x$base + } + else { + paste(x$base, ":", x$port, sep = "") + } +} diff --git a/man/describe.Rd b/man/describe.Rd new file mode 100644 index 0000000..515fa37 --- /dev/null +++ b/man/describe.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/describe.R +\name{describe} +\alias{describe} +\title{Explain a query} +\usage{ +describe(.data) +} +\arguments{ +\item{.data}{(list) input, using higher level interface} +} +\description{ +Explain a query +} +\examples{ +index("shakespeare") \%>\% range( speech_number <= 5 ) \%>\% describe + +index("shakespeare") \%>\% + bool(must_not = list(term=list(speaker="KING HENRY IV"))) \%>\% + describe + +index("geoshape") \%>\% + geoshape(field = "location", type = "envelope", + coordinates = list(c(-30, 50), c(30, 0))) \%>\% + describe() +} + From 5799c72c1be78d3c4147ad7c056b5eaaaf18ab7b Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Tue, 1 Mar 2016 16:27:52 -0800 Subject: [PATCH 11/22] some tidying, exec changes, update man files for new roxygen2 version --- DESCRIPTION | 1 + NAMESPACE | 4 +++- R/as.fjson.R | 5 ++++ R/exec.R | 5 ++++ R/query.R | 61 ++++++++++++++++++++++++++++------------------- R/utils.R | 5 +++- man/Search.Rd | 2 +- man/as.query.Rd | 2 +- man/elasticdsl.Rd | 2 +- man/filters.Rd | 2 +- man/hits.Rd | 2 +- man/index.Rd | 2 +- man/indices.Rd | 2 +- man/pipe.Rd | 2 +- man/query.Rd | 13 ++++++---- man/tabl.Rd | 2 +- man/utils.Rd | 24 ++++++++++--------- 17 files changed, 85 insertions(+), 51 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 2421745..55e5cd9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -19,3 +19,4 @@ Suggests: roxygen2, knitr, testthat +RoxygenNote: 5.0.1 diff --git a/NAMESPACE b/NAMESPACE index d9804c4..584f7bc 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,10 +1,11 @@ -# Generated by roxygen2 (4.1.1): do not edit by hand +# Generated by roxygen2: do not edit by hand S3method(as.query,bool) S3method(as.query,ids) S3method(as.query,params) S3method(as.query,prefix) S3method(as.query,range) +S3method(print,elasticdsl_query) S3method(print,index) export("%>%") export(Search_) @@ -15,6 +16,7 @@ export(boosting) export(boosting_) export(common) export(common_) +export(describe) export(exec) export(fbool) export(fbool_) diff --git a/R/as.fjson.R b/R/as.fjson.R index 76f093e..6339f3a 100644 --- a/R/as.fjson.R +++ b/R/as.fjson.R @@ -42,6 +42,11 @@ as.fjson.query <- function(x, ...){ jsonlite::toJSON(x, ..., auto_unbox = TRUE) } +as.fjson.esdsl <- function(x, ...){ + x <- list(query = list(range = parse_range(get_eq(x[[1]])))) + jsonlite::toJSON(x, ..., auto_unbox = TRUE) +} + as.fjson.range <- function(x, ...){ x <- list(query = list(range = parse_range(get_eq(x[[1]])))) jsonlite::toJSON(x, ..., auto_unbox = TRUE) diff --git a/R/exec.R b/R/exec.R index 52fff7a..8484cac 100644 --- a/R/exec.R +++ b/R/exec.R @@ -8,6 +8,11 @@ exec <- function(.obj, query, ...) { Search_(attr(.obj, "index"), body = tmp$body, params = tmp$params, ...) } +exec2 <- function(.obj, query, ...) { + pipe_autoexec(toggle = FALSE) + Search_(.obj$index, body = .obj$query, ...) +} + # execute on Search execute <- function(.obj, query){ Search_(.obj, body = query) diff --git a/R/query.R b/R/query.R index a94b260..291bbee 100644 --- a/R/query.R +++ b/R/query.R @@ -46,8 +46,9 @@ #' #' # range query #' index("shakespeare") %>% range( speech_number <= 5 ) -#' index("shakespeare") %>% range( speech_number <= c(1,5) ) # doens't work -#' index("shakespeare") %>% range( speech_number >= c(1,5) ) # doens't work +#' index("shakespeare") %>% range( speech_number >= 5 ) +#' # index("shakespeare") %>% range( speech_number <= c(1,5) ) # doens't work +#' # index("shakespeare") %>% range( speech_number >= c(1,5) ) # doens't work #' #' # geographic query #' ## point @@ -65,7 +66,11 @@ #' # polygon #' coords <- list(c(80.0, -20.0), c(-80.0, -20.0), c(-80.0, 60.0), c(40.0, 60.0), c(80.0, -20.0)) #' index("geoshape") %>% -#' geoshape(field = "location", type = "polygon", coordinates = coords) +#' geoshape(field = "location", type = "polygon", coordinates = coords) %>% +#' n() +#' +#' # common query - not working yet +#' # index("shakespeare") %>% common( speech_number <= 5 ) #' } NULL @@ -78,9 +83,11 @@ range <- function(.obj=list(), ..., boost=1, time_zone=NULL, execution=NULL, cac #' @export #' @rdname query range_ <- function(.obj=list(), ..., .dots) { + pipe_autoexec(toggle = TRUE) dots <- lazyeval::all_dots(.dots, ...) - query <- as.json(structure(dots, class=c("range","lazy_dots"))) - execute(.obj, query) + query <- as.json(structure(dots, class = c("range", "lazy_dots"))) + structure(list(index = .obj, query = query), class = "esdsl") + #execute(.obj, query) } #' @export @@ -92,61 +99,64 @@ bool <- function(.obj=list(), ...){ #' @export #' @rdname query bool_ <- function(.obj=list(), ..., .dots){ + pipe_autoexec(toggle = TRUE) dots <- lazyeval::all_dots(.dots, ...) - query <- as.json(structure(dots, class=c("bool","lazy_dots"))) - execute(.obj, query) + query <- as.json(structure(dots, class = c("bool","lazy_dots"))) + structure(list(index = .obj, query = query), class = "esdsl") + #execute(.obj, query) } #' @export #' @rdname query geoshape <- function(.obj=list(), ..., field=NULL){ - geoshape_(.obj, .dots = lazyeval::lazy_dots(...), field=field) + geoshape_(.obj, .dots = lazyeval::lazy_dots(...), field = field) } #' @export #' @rdname query geoshape_ <- function(.obj=list(), ..., .dots, field=NULL){ - pipe_autoexec(toggle = FALSE) + pipe_autoexec(toggle = TRUE) dots <- lazyeval::all_dots(.dots, ...) query <- as.json(structure(dots, class = c("geoshape", "lazy_dots")), field = field) - structure(.obj, class = "query", query = query) + structure(list(index = .obj, query = query), class = "esdsl") } #' @export #' @rdname query boosting <- function(.obj=list(), ..., negative_boost=NULL){ - boosting_(.obj, .dots = lazyeval::lazy_dots(...), negative_boost=negative_boost) + boosting_(.obj, .dots = lazyeval::lazy_dots(...), negative_boost = negative_boost) } #' @export #' @rdname query boosting_ <- function(.obj=list(), ..., .dots, negative_boost=NULL){ dots <- lazyeval::all_dots(.dots, ...) - query <- as.json(structure(dots, class=c("boosting","lazy_dots")), negative_boost=negative_boost) - execute(.obj, query) + query <- as.json(structure(dots, class = c("boosting", "lazy_dots")), negative_boost = negative_boost) + structure(list(index = .obj, query = query), class = "esdsl") + #execute(.obj, query) } #' @export #' @rdname query common <- function(.obj=list(), field, query=NULL, cutoff_frequency=NULL, low_freq_operator=NULL, minimum_should_match=NULL){ - common_(.obj, field=field, query=query, - cutoff_frequency=cutoff_frequency, - low_freq_operator=low_freq_operator, - minimum_should_match=minimum_should_match) + common_(.obj, field = field, query = query, + cutoff_frequency = cutoff_frequency, + low_freq_operator = low_freq_operator, + minimum_should_match = minimum_should_match) } #' @export #' @rdname query common_ <- function(.obj=list(), field, query=NULL, cutoff_frequency=NULL, low_freq_operator=NULL, minimum_should_match=NULL){ - args <- ec(list(field=field, query=query, - cutoff_frequency=cutoff_frequency, - low_freq_operator=low_freq_operator, - minimum_should_match=minimum_should_match)) + args <- ec(list(field = field, query = query, + cutoff_frequency = cutoff_frequency, + low_freq_operator = low_freq_operator, + minimum_should_match = minimum_should_match)) dots <- lazyeval::as.lazy_dots(args) query <- as.json( - structure(dots, class=c("common","lazy_dots")) + structure(dots, class = c("common", "lazy_dots")) ) execute(.obj, query) } @@ -168,8 +178,8 @@ as.json.bool <- function(x, ...){ as.json.geoshape <- function(x, field, ...){ out <- list() - for(i in seq_along(x)){ - dat <- if(is.character(x[[i]]$expr)){ + for (i in seq_along(x)) { + dat <- if (is.character(x[[i]]$expr)) { unbox(x[[i]]$expr) } else { list(eval(x[[i]]$expr)) @@ -204,7 +214,8 @@ get_eq <- function(y) { eq = dat$token[ dat$token %in% c("LT","GT","GE","LE","EQ_ASSIGN","EQ","NE") ], num = dat[ dat$token == "NUM_CONST", "text"] ) - tmp$eq <- switch(tolower(tmp$eq), lt="lt", gt="gt", ge="gte", le="lte", eq_assign=NA, eq=NA) + tmp$eq <- switch(tolower(tmp$eq), lt = "lt", gt = "gt", ge = "gte", + le = "lte", eq_assign = NA, eq = NA) tmp } diff --git a/R/utils.R b/R/utils.R index 8b07d0d..5f0600b 100644 --- a/R/utils.R +++ b/R/utils.R @@ -34,7 +34,10 @@ NULL #' @export #' @rdname utils -n <- function(x) x$hits$total +n <- function(.data) { + pipe_autoexec(toggle = FALSE) + exec2(structure(.data, class = "esdsl"))$hits$total +} #' @export #' @rdname utils diff --git a/man/Search.Rd b/man/Search.Rd index 3158f6d..6ac2ada 100644 --- a/man/Search.Rd +++ b/man/Search.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/search.R \name{Search_} \alias{Search_} diff --git a/man/as.query.Rd b/man/as.query.Rd index f581fc2..5520fb7 100644 --- a/man/as.query.Rd +++ b/man/as.query.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/as.query.R \name{as.query} \alias{as.query} diff --git a/man/elasticdsl.Rd b/man/elasticdsl.Rd index 08f6324..9537033 100644 --- a/man/elasticdsl.Rd +++ b/man/elasticdsl.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/elasticdsl-package.r \docType{package} \name{elasticdsl} diff --git a/man/filters.Rd b/man/filters.Rd index b20d916..4663a97 100644 --- a/man/filters.Rd +++ b/man/filters.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/filter.R \name{filters} \alias{and} diff --git a/man/hits.Rd b/man/hits.Rd index 605b63a..f559b59 100644 --- a/man/hits.Rd +++ b/man/hits.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/hits.R \name{hits} \alias{hits} diff --git a/man/index.Rd b/man/index.Rd index 8454598..b13c021 100644 --- a/man/index.Rd +++ b/man/index.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/index.R \name{index} \alias{index} diff --git a/man/indices.Rd b/man/indices.Rd index cc13053..97b7922 100644 --- a/man/indices.Rd +++ b/man/indices.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.0): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/index.R \name{indices} \alias{indices} diff --git a/man/pipe.Rd b/man/pipe.Rd index b1b12f8..036511e 100644 --- a/man/pipe.Rd +++ b/man/pipe.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pipe.R \name{\%>\%} \alias{\%>\%} diff --git a/man/query.Rd b/man/query.Rd index 89c1df9..be1e7ec 100644 --- a/man/query.Rd +++ b/man/query.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/query.R \name{query} \alias{bool} @@ -97,8 +97,9 @@ index("shakespeare") \%>\% # range query index("shakespeare") \%>\% range( speech_number <= 5 ) -index("shakespeare") \%>\% range( speech_number <= c(1,5) ) # doens't work -index("shakespeare") \%>\% range( speech_number >= c(1,5) ) # doens't work +index("shakespeare") \%>\% range( speech_number >= 5 ) +# index("shakespeare") \%>\% range( speech_number <= c(1,5) ) # doens't work +# index("shakespeare") \%>\% range( speech_number >= c(1,5) ) # doens't work # geographic query ## point @@ -116,7 +117,11 @@ index("geoshape") \%>\% # polygon coords <- list(c(80.0, -20.0), c(-80.0, -20.0), c(-80.0, 60.0), c(40.0, 60.0), c(80.0, -20.0)) index("geoshape") \%>\% - geoshape(field = "location", type = "polygon", coordinates = coords) + geoshape(field = "location", type = "polygon", coordinates = coords) \%>\% + n() + +# common query - not working yet +# index("shakespeare") \%>\% common( speech_number <= 5 ) } } diff --git a/man/tabl.Rd b/man/tabl.Rd index 2f2ce79..31ac028 100644 --- a/man/tabl.Rd +++ b/man/tabl.Rd @@ -1,4 +1,4 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand +% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tabl.R \name{tabl} \alias{tabl} diff --git a/man/utils.Rd b/man/utils.Rd index 2b6029f..3415a00 100644 --- a/man/utils.Rd +++ b/man/utils.Rd @@ -1,6 +1,6 @@ -% Generated by roxygen2 (4.1.1): do not edit by hand -% Please edit documentation in R/utils.R -\name{utils} +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/exec.R, R/utils.R +\name{exec} \alias{exec} \alias{fields} \alias{glimpse} @@ -9,13 +9,13 @@ \alias{sort} \alias{sort_} \alias{utils} -\title{elastic DSL utilities} +\title{Execute Elasticsearch query} \usage{ -n(x) +exec(.obj, query, ...) -glimpse(x, pretty = TRUE, ...) +n(.data) -exec(.obj, query, ...) +glimpse(x, pretty = TRUE, ...) fields(x, ...) @@ -26,21 +26,23 @@ sort(.obj = list(), ...) sort_(.obj = list(), ..., .dots) } \arguments{ -\item{x}{Input} +\item{.obj}{Input} -\item{pretty}{Pretty print} +\item{query}{Query statement} \item{...}{Further args passed on to \code{\link[jsonlite]{toJSON}}} -\item{.obj}{Input} +\item{x}{Input} -\item{query}{Query statement} +\item{pretty}{Pretty print} \item{y}{Input} \item{.dots}{Input} } \description{ +Execute Elasticsearch query + elastic DSL utilities } \details{ From f56382adb7c4ef026e1e30f29ec1ae03ef326f1f Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Tue, 1 Mar 2016 16:29:10 -0800 Subject: [PATCH 12/22] bump dev version and date, require newere roxygen2 to avoid man file conflicts --- DESCRIPTION | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 55e5cd9..d47e9e8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: elasticdsl Title: Elasticsearch DSL Description: Elasticsearch DSL. -Version: 0.0.3.9550 -Date: 2016-01-03 +Version: 0.0.3.9800 +Date: 2016-03-01 License: MIT + file LICENSE Authors@R: person("Scott", "Chamberlain", role = c("aut", "cre"), email = "myrmecocystus@gmail.com") @@ -16,7 +16,7 @@ Imports: lazyeval, dplyr Suggests: - roxygen2, + roxygen2 (>= 5.0.1), knitr, testthat RoxygenNote: 5.0.1 From ca6ac533db2c38ea3271f4612d1b56d86e730f16 Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Tue, 1 Mar 2016 16:31:36 -0800 Subject: [PATCH 13/22] put in code to connect to ES before examples in describe --- R/describe.R | 2 ++ man/describe.Rd | 2 ++ 2 files changed, 4 insertions(+) diff --git a/R/describe.R b/R/describe.R index f46b0a3..81bfd05 100644 --- a/R/describe.R +++ b/R/describe.R @@ -3,6 +3,8 @@ #' @export #' @param .data (list) input, using higher level interface #' @examples +#' elastic::connect() +#' #' index("shakespeare") %>% range( speech_number <= 5 ) %>% describe #' #' index("shakespeare") %>% diff --git a/man/describe.Rd b/man/describe.Rd index 515fa37..acaee13 100644 --- a/man/describe.Rd +++ b/man/describe.Rd @@ -13,6 +13,8 @@ describe(.data) Explain a query } \examples{ +elastic::connect() + index("shakespeare") \%>\% range( speech_number <= 5 ) \%>\% describe index("shakespeare") \%>\% From edbff97a074e59fa7d2bd46d5f442dcff2eeddf2 Mon Sep 17 00:00:00 2001 From: Scott Chamberlain Date: Sun, 6 Mar 2016 09:12:16 -0800 Subject: [PATCH 14/22] tweak to test-all: load elastic first, then docs bulk --- tests/test-all.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test-all.R b/tests/test-all.R index 2ee8c54..92cae72 100644 --- a/tests/test-all.R +++ b/tests/test-all.R @@ -1,7 +1,7 @@ library('testthat') library('elasticdsl') -if(Sys.getenv("ES_IP") != "") { +if (Sys.getenv("ES_IP") != "") { # The ES_IP environmental var can be set the root ip of the # Elasticsearch for convenience. Continuous integration uses # the default localhost address. @@ -14,6 +14,7 @@ if(Sys.getenv("ES_IP") != "") { invisible(elastic::connect()) } +library('elastic') shakespeare <- system.file("examples", "shakespeare_data.json", package = "elastic") invisible(elastic::docs_bulk(shakespeare)) gbif <- system.file("examples", "gbif_data.json", package = "elastic") From 33b95c7c415e9fef818a8c21847b46427d7316bf Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 6 Mar 2016 10:16:59 -0600 Subject: [PATCH 15/22] Load index before trying to run describe example on CI --- R/describe.R | 3 ++- man/describe.Rd | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/R/describe.R b/R/describe.R index 81bfd05..8a6e3c3 100644 --- a/R/describe.R +++ b/R/describe.R @@ -4,7 +4,8 @@ #' @param .data (list) input, using higher level interface #' @examples #' elastic::connect() -#' +#' shakespeare <- system.file("examples", "shakespeare_data.json", package = "elastic") +#' docs_bulk(shakespeare) #' index("shakespeare") %>% range( speech_number <= 5 ) %>% describe #' #' index("shakespeare") %>% diff --git a/man/describe.Rd b/man/describe.Rd index acaee13..fcf8e59 100644 --- a/man/describe.Rd +++ b/man/describe.Rd @@ -14,7 +14,8 @@ Explain a query } \examples{ elastic::connect() - +shakespeare <- system.file("examples", "shakespeare_data.json", package = "elastic") +docs_bulk(shakespeare) index("shakespeare") \%>\% range( speech_number <= 5 ) \%>\% describe index("shakespeare") \%>\% From 466de926dca9352ee6081ce7ac323457ce980987 Mon Sep 17 00:00:00 2001 From: statwonk Date: Sat, 12 Mar 2016 13:38:55 -0600 Subject: [PATCH 16/22] Add exec params to documentation. --- R/exec.R | 4 ++++ man/utils.Rd | 12 +++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/R/exec.R b/R/exec.R index 8484cac..b72bd34 100644 --- a/R/exec.R +++ b/R/exec.R @@ -1,5 +1,9 @@ #' Execute Elasticsearch query #' +#' @param .obj +#' @param query +#' @param ... +#' #' @export #' @rdname utils exec <- function(.obj, query, ...) { diff --git a/man/utils.Rd b/man/utils.Rd index 3415a00..5d037af 100644 --- a/man/utils.Rd +++ b/man/utils.Rd @@ -26,11 +26,11 @@ sort(.obj = list(), ...) sort_(.obj = list(), ..., .dots) } \arguments{ -\item{.obj}{Input} +\item{.obj}{} -\item{query}{Query statement} +\item{query}{} -\item{...}{Further args passed on to \code{\link[jsonlite]{toJSON}}} +\item{...}{} \item{x}{Input} @@ -39,6 +39,12 @@ sort_(.obj = list(), ..., .dots) \item{y}{Input} \item{.dots}{Input} + +\item{.obj}{Input} + +\item{query}{Query statement} + +\item{...}{Further args passed on to \code{\link[jsonlite]{toJSON}}} } \description{ Execute Elasticsearch query From dbde65be3f40aaa6162fc5c28efadcc4597f0579 Mon Sep 17 00:00:00 2001 From: statwonk Date: Sat, 12 Mar 2016 17:45:13 -0600 Subject: [PATCH 17/22] Add missing params to documentation. --- R/exec.R | 4 ---- R/utils.R | 4 ++++ man/utils.Rd | 16 +++++++--------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/R/exec.R b/R/exec.R index b72bd34..8484cac 100644 --- a/R/exec.R +++ b/R/exec.R @@ -1,9 +1,5 @@ #' Execute Elasticsearch query #' -#' @param .obj -#' @param query -#' @param ... -#' #' @export #' @rdname utils exec <- function(.obj, query, ...) { diff --git a/R/utils.R b/R/utils.R index 5f0600b..9585dc4 100644 --- a/R/utils.R +++ b/R/utils.R @@ -32,6 +32,10 @@ #' } NULL +#' The number of returned documents +#' +#' @param .data A list returned by a query +#' #' @export #' @rdname utils n <- function(.data) { diff --git a/man/utils.Rd b/man/utils.Rd index 5d037af..3122fd4 100644 --- a/man/utils.Rd +++ b/man/utils.Rd @@ -26,11 +26,13 @@ sort(.obj = list(), ...) sort_(.obj = list(), ..., .dots) } \arguments{ -\item{.obj}{} +\item{.obj}{Input} + +\item{query}{Query statement} -\item{query}{} +\item{...}{Further args passed on to \code{\link[jsonlite]{toJSON}}} -\item{...}{} +\item{.data}{A list returned by a query} \item{x}{Input} @@ -39,17 +41,13 @@ sort_(.obj = list(), ..., .dots) \item{y}{Input} \item{.dots}{Input} - -\item{.obj}{Input} - -\item{query}{Query statement} - -\item{...}{Further args passed on to \code{\link[jsonlite]{toJSON}}} } \description{ Execute Elasticsearch query elastic DSL utilities + +The number of returned documents } \details{ Various utilities. From b2a274d71bfdc9c85424b2b95419a9e02e23022c Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 6 Mar 2016 09:17:08 -0600 Subject: [PATCH 18/22] Add tests to filters, index, pipers and search --- R/describe.R | 8 +++++-- man/describe.Rd | 8 +++++-- tests/testthat/test-filter.R | 45 +++++++++++++++++++++++++++++++++++- tests/testthat/test-index.R | 12 ++++++---- tests/testthat/test-pipers.R | 8 +++++++ 5 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 tests/testthat/test-pipers.R diff --git a/R/describe.R b/R/describe.R index 8a6e3c3..dd31432 100644 --- a/R/describe.R +++ b/R/describe.R @@ -4,18 +4,22 @@ #' @param .data (list) input, using higher level interface #' @examples #' elastic::connect() +#' #' shakespeare <- system.file("examples", "shakespeare_data.json", package = "elastic") -#' docs_bulk(shakespeare) -#' index("shakespeare") %>% range( speech_number <= 5 ) %>% describe +#' invisible(elastic::docs_bulk(shakespeare)) +#' # index("shakespeare") %>% range( speech_number <= 5 ) %>% describe #' #' index("shakespeare") %>% #' bool(must_not = list(term=list(speaker="KING HENRY IV"))) %>% #' describe #' +#' geoshape <- system.file("examples", "gbif_geoshape.json", package = "elastic") +#' invisible(elastic::docs_bulk(geoshape)) #' index("geoshape") %>% #' geoshape(field = "location", type = "envelope", #' coordinates = list(c(-30, 50), c(30, 0))) %>% #' describe() +#' describe <- function(.data) { pipe_autoexec(toggle = FALSE) if (!inherits(.data, "esdsl")) stop("must be of class esdsl", call. = FALSE) diff --git a/man/describe.Rd b/man/describe.Rd index fcf8e59..8e5607a 100644 --- a/man/describe.Rd +++ b/man/describe.Rd @@ -14,17 +14,21 @@ Explain a query } \examples{ elastic::connect() + shakespeare <- system.file("examples", "shakespeare_data.json", package = "elastic") -docs_bulk(shakespeare) -index("shakespeare") \%>\% range( speech_number <= 5 ) \%>\% describe +invisible(elastic::docs_bulk(shakespeare)) +# index("shakespeare") \%>\% range( speech_number <= 5 ) \%>\% describe index("shakespeare") \%>\% bool(must_not = list(term=list(speaker="KING HENRY IV"))) \%>\% describe +geoshape <- system.file("examples", "gbif_geoshape.json", package = "elastic") +invisible(elastic::docs_bulk(geoshape)) index("geoshape") \%>\% geoshape(field = "location", type = "envelope", coordinates = list(c(-30, 50), c(30, 0))) \%>\% describe() + } diff --git a/tests/testthat/test-filter.R b/tests/testthat/test-filter.R index e008790..05a02a0 100644 --- a/tests/testthat/test-filter.R +++ b/tests/testthat/test-filter.R @@ -1,7 +1,50 @@ context("filter.R") +first_available_index <- indices()[[1]] -test_that("functions return the correct classes", { +test_that("filter", { expect_true("filtered" %in% class(filter(NULL))) }) +test_that("ids", { + expect_true("comb" %in% class(ids_(c(1, 2)))) + expect_true("ids" %in% class(ids_(c(1, 2))[[1]])) +}) + +test_that("ids_", { + expect_true("comb" %in% class(ids_(c(1, 2)))) + expect_true("ids" %in% class(ids_(c(1, 2))[[1]])) +}) + +test_that("ids", { + expect_equal( + index("shakespeare") %>% + filter() %>% + ids(c(1, 2)) %>% + exec() %>% + hits() %>% + sapply(., FUN = function(i) { i$`_id` }) %>% + as.integer() %>% + sort.default(), + c(1, 2)) +}) + +test_that("operands", { + expect_equal(index("shakespeare") %>% and() %>% attr("operand"), "and") + expect_equal(index("shakespeare") %>% or() %>% attr("operand"), "or") + expect_equal(index("shakespeare") %>% not() %>% attr("operand"), "not") +}) + +test_that("exec", { + expect_true( + index("shakespeare") %>% + filter() %>% + prefix(speaker = "KING H") %>% + exec() %>% + hits() %>% + sapply(., FUN = function(i) { i$`_source`$speaker }) %>% + grepl("KING HENRY IV", .) %>% + all() + ) +}) + diff --git a/tests/testthat/test-index.R b/tests/testthat/test-index.R index e83e25b..502e4d4 100644 --- a/tests/testthat/test-index.R +++ b/tests/testthat/test-index.R @@ -1,12 +1,16 @@ context("index.R") +first_available_index <- indices()[[1]] + test_that("index() returns the right class", { - # Using the ES_IP env var to pass in the - # cluster's ip. - expect_equal(class(index("gbif")), "index") + expect_equal(class(index(first_available_index)), "index") }) test_that("indices returns at least one index", { - expect_gt(length(indices()), 0) + expect_more_than(length(indices()), 0) +}) + +test_that("get_map", { + expect_is(names(elasticdsl:::get_map(first_available_index)), "character") }) diff --git a/tests/testthat/test-pipers.R b/tests/testthat/test-pipers.R new file mode 100644 index 0000000..6083442 --- /dev/null +++ b/tests/testthat/test-pipers.R @@ -0,0 +1,8 @@ +context("pipers.R") + +test_that("pipline_info()", { + expect_named(elasticdsl:::pipeline_info(), c("is_piped", "env")) + expect_is(index("shakespeare") %>% { elasticdsl:::pipeline_info() }, "list") + expect_true(index("shakespeare") %>% { elasticdsl:::pipeline_info() } %>% .$is_piped) + expect_false((elasticdsl:::pipeline_info())$is_piped) +}) From 91668357a678756d80e3bc77dbc075c77c1f19cd Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 11:15:48 -0600 Subject: [PATCH 19/22] Prototype of an aggs parser handle --- NAMESPACE | 1 + R/aggs.R | 42 ++++++++++++++++++++++++++++++++++++++++++ man/aggs.Rd | 31 +++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 R/aggs.R create mode 100644 man/aggs.Rd diff --git a/NAMESPACE b/NAMESPACE index 584f7bc..ab0318e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -9,6 +9,7 @@ S3method(print,elasticdsl_query) S3method(print,index) export("%>%") export(Search_) +export(aggs) export(and) export(bool) export(bool_) diff --git a/R/aggs.R b/R/aggs.R new file mode 100644 index 0000000..9646b0e --- /dev/null +++ b/R/aggs.R @@ -0,0 +1,42 @@ +#' elastic DSL aggs +#' +#' @name aggs +#' +#' @param .obj An index object. If nothing passed defaults to all indices, equivalent to +#' doing e.g., \code{localhost:9200/_search} +#' @param ... Further args passed on +NULL + +#' Aggregations +#' +#' @export +#' @rdname aggs +#' +#' +#' @examples +#' target <- Search( +#' index = "gbif", +#' body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) +#' +#' aggs_example <- index("gbif") %>% +#' aggs(x = list(statistic = list(avg = list(field = "decimalLatitude")))) +#' +#' identical(target$aggregations, aggs_example$aggregations) +#' +aggs <- function(.obj = list(), ...) { + aggs_(.obj, .dots = lazyeval::lazy_dots(...)) +} + +aggs_ <- function(.obj=list(), ..., .dots) { + dots <- lazyeval::all_dots(.dots, ...) + + as.json.aggs <- function(x, ...) { + jsonlite::toJSON(list(aggs = x), ..., auto_unbox = TRUE) + } + + query <- as.json.aggs(structure(lazy_eval(dots$x), class=c("aggs", "lazy_dots", "list"))) + execute <- function(.obj, query){ + Search_(.obj, body = query) + } + execute(.obj, query) +} diff --git a/man/aggs.Rd b/man/aggs.Rd new file mode 100644 index 0000000..57ba400 --- /dev/null +++ b/man/aggs.Rd @@ -0,0 +1,31 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/aggs.R +\name{aggs} +\alias{aggs} +\title{elastic DSL aggs} +\usage{ +aggs(.obj = list(), ...) +} +\arguments{ +\item{.obj}{An index object. If nothing passed defaults to all indices, equivalent to +doing e.g., \code{localhost:9200/_search}} + +\item{...}{Further args passed on} +} +\description{ +elastic DSL aggs + +Aggregations +} +\examples{ +target <- Search( +index = "gbif", +body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) + +aggs_example <- index("gbif") \%>\% + aggs(x = list(statistic = list(avg = list(field = "decimalLatitude")))) + +identical(target$aggregations, aggs_example$aggregations) + +} + From eec3cd6f3c77472b952427ebea18e8f98c7b9568 Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 11:25:09 -0600 Subject: [PATCH 20/22] Remove duplicate function --- R/zzz.r | 2 -- 1 file changed, 2 deletions(-) diff --git a/R/zzz.r b/R/zzz.r index 2fdc91c..73feb79 100644 --- a/R/zzz.r +++ b/R/zzz.r @@ -1,7 +1,5 @@ ec <- function (l) Filter(Negate(is.null), l) -ec <- function (l) Filter(Negate(is.null), l) - cl <- function(x) if(is.null(x)) NULL else paste0(x, collapse = ",") pluck <- function(x, name, type) { From b8ff7c116b5ce8bb8f528fd8594b794e91d6d17a Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 11:33:18 -0600 Subject: [PATCH 21/22] Help CI know where the Search function comes from --- R/aggs.R | 1 + man/aggs.Rd | 1 + 2 files changed, 2 insertions(+) diff --git a/R/aggs.R b/R/aggs.R index 9646b0e..2aac905 100644 --- a/R/aggs.R +++ b/R/aggs.R @@ -14,6 +14,7 @@ NULL #' #' #' @examples +#' library(elastic) #' target <- Search( #' index = "gbif", #' body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) diff --git a/man/aggs.Rd b/man/aggs.Rd index 57ba400..db1ae6c 100644 --- a/man/aggs.Rd +++ b/man/aggs.Rd @@ -18,6 +18,7 @@ elastic DSL aggs Aggregations } \examples{ +library(elastic) target <- Search( index = "gbif", body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) From d591fb54dcfed8773c3626284077c28c030ca8c7 Mon Sep 17 00:00:00 2001 From: Christopher Peters Date: Sun, 28 Feb 2016 20:15:10 -0600 Subject: [PATCH 22/22] Remove example that causes CI to fail --- R/aggs.R | 12 ------------ man/aggs.Rd | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/R/aggs.R b/R/aggs.R index 2aac905..25ea9a6 100644 --- a/R/aggs.R +++ b/R/aggs.R @@ -12,18 +12,6 @@ NULL #' @export #' @rdname aggs #' -#' -#' @examples -#' library(elastic) -#' target <- Search( -#' index = "gbif", -#' body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) -#' -#' aggs_example <- index("gbif") %>% -#' aggs(x = list(statistic = list(avg = list(field = "decimalLatitude")))) -#' -#' identical(target$aggregations, aggs_example$aggregations) -#' aggs <- function(.obj = list(), ...) { aggs_(.obj, .dots = lazyeval::lazy_dots(...)) } diff --git a/man/aggs.Rd b/man/aggs.Rd index db1ae6c..845ed35 100644 --- a/man/aggs.Rd +++ b/man/aggs.Rd @@ -17,16 +17,4 @@ elastic DSL aggs Aggregations } -\examples{ -library(elastic) -target <- Search( -index = "gbif", -body = list(aggs = list(statistic = list(avg = list(field = "decimalLatitude"))))) - -aggs_example <- index("gbif") \%>\% - aggs(x = list(statistic = list(avg = list(field = "decimalLatitude")))) - -identical(target$aggregations, aggs_example$aggregations) - -}