Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

271 lines (237 sloc) 7.486 kB
require 'faraday'
require 'yajl'
require 'time'
module ElasticSearch
class JSONResponse < Faraday::Response::Middleware
def parse(body)
Yajl.load body
end
end
class Error < StandardError
end
def self.get_connection(server)
return unless server
Faraday.new(:url => server) do |builder|
# TODO: add timeout middleware
builder.request :json
# builder.response :logger
builder.use JSONResponse
builder.adapter :excon
end
end
def self.available?
conn = get_connection
resp = conn.get '/'
resp.status == 200
end
# Object to represent an ElasticSearch property mapping
class PropertyMapping < Struct.new(:name, :type)
end
# Object to represent an index in elasticsearch
class Index
def initialize(name, server)
@name = name
@server = server
@conn = ElasticSearch.get_connection(server)
end
# Some helpers for making REST calls to elasticsearch
%w[ get post put delete head ].each do |method|
class_eval <<-EOC, __FILE__, __LINE__
def #{method}(*args, &blk)
raise Error, "no connection" unless @conn
resp = @conn.#{method}(*args, &blk)
raise Error, "elasticsearch server is offline or not accepting requests" if resp.status == 0
raise Error, resp.body['error'] if resp.body && resp.body['error']
@last_resp = resp
resp.body
end
EOC
end
# Check if the index exists.
#
# Returns true if the index exists, false otherwise.
def exists?
get("/#{@name}/_status")['error'].nil?
rescue ElasticSearch::Error
false
end
# Destroy the index.
#
# Returns a hash, the parsed response body from elasticsearch.
def destroy
delete "/#{@name}"
end
# Clear all content from the index
#
# Returns a hash, the parsed response body from elasticsearch
def clear
delete "/#{@name}/_all"
end
# Create the index.
#
# server - elasticsearch base URL
# create_options - a hash of index creation options
#
# Returns a hash, the parsed response body from elasticsearch.
def create(create_options={})
self.class.create @name, @server, create_options
end
# Force a refresh of this index
#
# This basically tells elasticsearch to flush it's buffers
# but not clear caches (unlike a commit in Solr)
# "Commits" happen automatically and are managed by elasticsearch
#
# Returns a hash, the parsed response body from elasticsearch
def refresh
post "/#{@name}/_refresh"
end
def bulk(data)
return if data.empty?
body = post "/#{@name}/_bulk", data
raise Error, "bulk import got HTTP #{@last_resp.status} response" if @last_resp.status != 200
end
# Grab a bunch of items from this index
#
# type - the type to pull from
# ids - an Array of ids to fetch
#
# Returns a hash, the parsed response body from elasticsearch
def mget(type, ids)
get do |req|
req.url "#{@name}/#{type}/_mget"
req.body = {'ids' => ids}
end
end
# Grab all the items from this index
#
# type - the type to pull from
#
# Returns a hash, the parsed response body from elasticsearch
def all(type)
get do |req|
req.url "#{@name}/#{type}/_search", 'q' => '*'
end
end
# Search this index using a post body
#
# types - the type or types (comma seperated) to search
# options - options hash for this search request
#
# Returns a hash, the parsed response body from elasticsearch
def search(types, options)
get do |req|
req.url "#{@name}/#{types}/_search"
req.body = options
end
end
# Search this index using a query string
#
# types - the type or types (comma seperated) to search
# query - the search query string
# options - options hash for this search request (optional)
#
# Returns a hash, the parsed response body from elasticsearch
def query(types, query, options={})
query = {'q' => query} if query.is_a?(String)
get do |req|
req.url "#{@name}/#{types}/_search", query.merge(options)
req.body = options if options
end
end
# Count results using a query string
#
# types - the type or types (comma seperated) to search
# query - the search query string
# options - options hash for this search request (optional)
#
# Returns a hash, the parsed response body from elasticsearch
def count(types, query={}, options=nil)
query = {'q' => query} if query.is_a?(String)
get do |req|
req.url "#{@name}/#{types}/_count", query
req.body = options if options
end
end
# Add a document to this index
#
# type - the type of this document
# id - the unique identifier for this document
# doc - the document to be indexed
#
# Returns a hash, the parsed response body from elasticsearch
def add(type, id, doc, params={})
doc.each do |key, val|
# make sure dates are in a consistent format for indexing
doc[key] = val.iso8601 if val.respond_to?(:iso8601)
end
put do |req|
req.url "/#{@name}/#{type}/#{id}", params
req.body = doc
end
end
# Remove a document from this index
#
# type - the type of document to be removed
# id - the unique identifier of the document to be removed
#
# Returns a hash, the parsed response body from elasticsearch
def remove(type, id)
delete do |req|
req.url "#{@name}/#{type}/#{id}"
end
end
# Remove a collection of documents matched by a query
#
# types - the type or types to query
# options - the search options hash
#
# Returns a hash, the parsed response body from elasticsearch
def remove_by_query(types, options)
delete do |req|
req.url "#{@name}/#{types}/_query"
req.body = options
end
end
# Mapping for the specified type.
#
# type - type to get the mapping for
#
# Returns a hash, the mapping for the specified type
def mapping(type)
get do |req|
req.url "#{@name}/#{type}/_mapping"
end
end
# Update ElasticSearch's mapping for the specified type
#
# type - type whose mapping we're updating
# properties - array of PropertyMappings
#
# Returns a hash, the parsed response body from elasticsearch
def update_mapping(type, *properties)
properties_for_body = {}
properties.each do |property|
properties_for_body[property.name] = { 'type' => property.type }
end
put do |req|
req.url "#{@name}/#{type}/_mapping"
req.body = { type => { 'properties' => properties_for_body } }
end
end
# Create a new index in elasticsearch
#
# name - the name of the index to be created
# server - URL for the connection
# create_options - a hash of index creation options
#
# Returns a new ElasticSearch::Index instance
def self.create(name, server, create_options={})
ElasticSearch.get_connection(server).put do |req|
req.url "/#{name}"
req.body = create_options
end
new name, server
end
end
end
Jump to Line
Something went wrong with that request. Please try again.