0.0
No commit activity in last 3 years
No release in over 3 years
Powerful and flexible elasticsearch query factory for you ruby application
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Project Readme

Elasticquery

Gem Version Build Status Code Climate Test Coverage

A module for elasticsearch-rails libraries like as user-friendly query generator.

Abstract

Elastic query ruby DSL is not a fresh idea. elasticsearch-rails has fully flexible language and recommends to use json generators for building complex queries. I hope, in most cases you don't need full complex setup. Elasticquery going to process your form parameters and build valid query using Filters and Queries elastic query methods. All rules are joined by AND condition, invalid or blank rules are ignored.

Elasticquery supports term (usable with HTML select tag), range, exists and missing. multi_match query for simple index searching. All filters and queries are configurable.

Elasticquery is in active development. I recommend to use it CAREFULLY for production

Installation

To install using Bundler grab the latest stable version:

gem 'elasticquery'

To manually install elasticquery via Rubygems simply gem install:

gem install elasticquery

Getting Started

First instruction

Elasticquery was designed to be customized as you need to. Providing simple methods it allows you to build flexible queries using Elastic Query DSL

class MyQuery < Elasticquery::Base
  filtered do |params|
    filters do
      term "user.id" => params[:user_id]
      range.not :age, gte: 18
    end
    queries do
      multi_match params[:query]
    end
  end
end
query = MyQuery.new query: 'i typed', user_id: 5
query.build # => query for elastic
Article.search query.build # => returns result 

Currently you have

Filters

Term

# Simple one term filter
term category: 'Rock'

# _cache option support
term category: 'Soul', _cache: false

# Blank values are skipped. This query returns all records
term name: " "

Terms

# Standard terms options
terms a: 1, b: 2

# Skip empty values
terms a: 1, b: "" # => {a: 1} wil be passed

# Blank terms are skipped
terms a: "", b: nil # => match_all will be executed

# _cache and execution support
terms a: 1, b: 2, _cache: false, execution: "or"

# where alias. Usable in chain calls
where a: 1, b: 2, c: 3

Range

# One side range
range :age, gte: 18

# Double sides range
range :volume, gte: 1, lte: 100

# _cache and execution options support
range :volume, gte: 1, lte: 100, _cache: true, execution: "fielddata"

Exists Missing

# Field existence check
exists "last_name"
missing "last_name"

# Blank value skipped
exists ""
missing ""

# Has with alias
with 'first_name'
without 'first_name'

Not

# Blank values are skipped. This query returns all records
range.not :age, lte: ' ', gte: nil

# Term exclusion
term.not category: 'Rap'

# Terms exclusion
terms.not category: 'Rap', name: "Guf"

# 'Exists not' uses missing
with.not #=> returns missing filter

All filters are joined by AND filter.

Queries

MultiMatch

# Simple all fields search in your index
multi_match 'developers'

# The same as above
multi_match 'developers', fields: "_all", operator: "and", type: "best_fields"

# Configure fields
multi_match 'Jordan', fields: ['first_name', 'last_name'], operator: "or"

# Blank values are skipped. This query returns all records
multi_match ''

# Alias as search
search 'Hello!'

Extended instruction

There are multiple ways to organize your query, using chaining calls, or custom filters.

  • Chain calls
PeopleQuery.new.queries.multi_match('hi', operator: :or).filters.term(age: 21).build # => returns hash
Query.new.queries./queries-chain/.filters./filters-chain/
  • Class methods
class PeopleQuery < Elasticquery::Base
  filtered do |params|
    filters do
      range :age, lte: prepare_age(params[:max_age])
    end
  end

  protected

  def prepare_age(param)
    param.to_i
  end
end
PeopleQuery.build(max_age: '42') # => result
  • Multiple filtered blocks
class ChildQuery < Elasticquery::Base
  filtered do |params|
    filters do
      term :'category.id' => params[:category_id]
    end
  end

  filtered do |params|
    filters do
      term :'author.id' => User.find(params[:user_id]).name
    end
  end
end
ChildQuery.build({user_id: 1, category_id: 14}) => returns both user and category filters
  • Query inheritance
class ParentQuery < Elasticquery::Base
  filtered do |params|
    filters do
      term :'category.id' => params[:category_id]
    end
  end
end

class ChildQuery < ParentQuery
  filtered do |params|
    filters do
      term :'author.id' => User.find(params[:user_id]).name
    end
  end
end

ChildQuery.build({user_id: 1, category_id: 14}) => # the same as in previous example
  • Elasticsearch::Model support with es shortcut
class Article
  include Elasticsearch::Model
  extend Elasticquery::Es
end

Article.es.filters.term(user_id: 12).with("published_at").queries.search("Verge").results # => collection of "hits"
Article.es.filters.term(user_id: 12).with("published_at").queries.search("Verge").records # => collection of records from db