stretcher 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +1 -0
- data/lib/stretcher/es_component.rb +9 -3
- data/lib/stretcher/index.rb +5 -1
- data/lib/stretcher/index_type.rb +11 -2
- data/lib/stretcher/request_error.rb +4 -1
- data/lib/stretcher/search_results.rb +5 -3
- data/lib/stretcher/server.rb +5 -1
- data/lib/stretcher/util.rb +1 -1
- data/lib/stretcher/version.rb +1 -1
- data/spec/lib/stretcher_index_spec.rb +20 -2
- data/spec/lib/stretcher_index_type_spec.rb +46 -15
- metadata +2 -2
    
        data/README.md
    CHANGED
    
    
| @@ -4,9 +4,9 @@ module Stretcher | |
| 4 4 |  | 
| 5 5 | 
             
                # Many of the methods marked protected are called by one line shims in subclasses. This is mostly to facilitate
         | 
| 6 6 | 
             
                # better looking rdocs
         | 
| 7 | 
            -
             | 
| 7 | 
            +
             | 
| 8 8 | 
             
                private
         | 
| 9 | 
            -
             | 
| 9 | 
            +
             | 
| 10 10 | 
             
                def do_search(generic_opts={}, explicit_body=nil)
         | 
| 11 11 | 
             
                  query_opts = {}
         | 
| 12 12 | 
             
                  body = nil
         | 
| @@ -21,7 +21,7 @@ module Stretcher | |
| 21 21 | 
             
                  response = request(:get, "_search", query_opts) do |req|
         | 
| 22 22 | 
             
                    req.body = body
         | 
| 23 23 | 
             
                  end
         | 
| 24 | 
            -
                  SearchResults.new(:raw => response) | 
| 24 | 
            +
                  SearchResults.new(:raw => response)
         | 
| 25 25 | 
             
                end
         | 
| 26 26 |  | 
| 27 27 | 
             
                def do_refresh
         | 
| @@ -33,5 +33,11 @@ module Stretcher | |
| 33 33 | 
             
                  raise "Cannot issue request, no server specified!" unless @server
         | 
| 34 34 | 
             
                  @server.request(method, prefixed_path, query_opts, *args, &block)
         | 
| 35 35 | 
             
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def do_delete_query(query)
         | 
| 38 | 
            +
                  request :delete, '_query' do |req|
         | 
| 39 | 
            +
                    req.body = query
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 36 42 | 
             
              end
         | 
| 37 43 | 
             
            end
         | 
    
        data/lib/stretcher/index.rb
    CHANGED
    
    | @@ -78,6 +78,10 @@ module Stretcher | |
| 78 78 | 
             
                  false
         | 
| 79 79 | 
             
                end
         | 
| 80 80 |  | 
| 81 | 
            +
                def delete_query(query)
         | 
| 82 | 
            +
                  do_delete_query(query)
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 81 85 | 
             
                # Issues a search with the given query opts and body, both should be hashes
         | 
| 82 86 | 
             
                #
         | 
| 83 87 | 
             
                #    res = server.index('foo').search(size: 12, {query: {match_all: {}}})
         | 
| @@ -117,7 +121,7 @@ module Stretcher | |
| 117 121 | 
             
                    req.body = text
         | 
| 118 122 | 
             
                  end
         | 
| 119 123 | 
             
                end
         | 
| 120 | 
            -
             | 
| 124 | 
            +
             | 
| 121 125 | 
             
                # Perform a refresh making all items in this index available instantly
         | 
| 122 126 | 
             
                def refresh
         | 
| 123 127 | 
             
                  do_refresh
         | 
    
        data/lib/stretcher/index_type.rb
    CHANGED
    
    | @@ -13,6 +13,7 @@ module Stretcher | |
| 13 13 |  | 
| 14 14 | 
             
                # Retrieves the document by ID
         | 
| 15 15 | 
             
                # Normally this returns the contents of _source, however, the 'raw' flag is passed in, it will return the full response hash
         | 
| 16 | 
            +
                # Returns nil if the document does not exist
         | 
| 16 17 | 
             
                def get(id, raw=false)
         | 
| 17 18 | 
             
                  res = request(:get, id)
         | 
| 18 19 | 
             
                  raw ? res : res["_source"]
         | 
| @@ -23,6 +24,11 @@ module Stretcher | |
| 23 24 | 
             
                  request(:put, id, source)
         | 
| 24 25 | 
             
                end
         | 
| 25 26 |  | 
| 27 | 
            +
                # Index an item with automatic ID generation
         | 
| 28 | 
            +
                def post(source)
         | 
| 29 | 
            +
                  request(:post, nil, source)
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 26 32 | 
             
                # Uses the update api to modify a document with a script
         | 
| 27 33 | 
             
                # To update a doc with ID 987 for example:
         | 
| 28 34 | 
             
                # type.update(987, script: "ctx._source.message = 'Updated!'")
         | 
| @@ -63,11 +69,14 @@ module Stretcher | |
| 63 69 | 
             
                def exists?(id=nil)
         | 
| 64 70 | 
             
                  request :head, id
         | 
| 65 71 | 
             
                  true
         | 
| 66 | 
            -
                rescue Stretcher::RequestError => e
         | 
| 67 | 
            -
                  raise e if e.http_response.status != 404
         | 
| 72 | 
            +
                rescue Stretcher::RequestError::NotFound => e
         | 
| 68 73 | 
             
                  false
         | 
| 69 74 | 
             
                end
         | 
| 70 75 |  | 
| 76 | 
            +
                def delete_query(query)
         | 
| 77 | 
            +
                  do_delete_query(query)
         | 
| 78 | 
            +
                end
         | 
| 79 | 
            +
             | 
| 71 80 | 
             
                # Issues an Index#search scoped to this type
         | 
| 72 81 | 
             
                # See Index#search for more details
         | 
| 73 82 | 
             
                def search(generic_opts={}, explicit_body=nil)
         | 
| @@ -2,9 +2,12 @@ module Stretcher | |
| 2 2 | 
             
              # Raised when the underlying http status of an operation != 200
         | 
| 3 3 | 
             
              class RequestError < StandardError
         | 
| 4 4 | 
             
                attr_reader :http_response
         | 
| 5 | 
            -
             | 
| 5 | 
            +
             | 
| 6 6 | 
             
                def initialize(http_response)
         | 
| 7 7 | 
             
                  @http_response = http_response
         | 
| 8 8 | 
             
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                class NotFound < RequestError
         | 
| 11 | 
            +
                end
         | 
| 9 12 | 
             
              end
         | 
| 10 13 | 
             
            end
         | 
| @@ -18,9 +18,11 @@ module Stretcher | |
| 18 18 | 
             
                  super
         | 
| 19 19 | 
             
                  self.total = raw.hits.total
         | 
| 20 20 | 
             
                  self.facets = raw.facets
         | 
| 21 | 
            -
                  self.results = raw.hits.hits.collect  | 
| 22 | 
            -
                     | 
| 23 | 
            -
             | 
| 21 | 
            +
                  self.results = raw.hits.hits.collect do |r|
         | 
| 22 | 
            +
                    k = ['_source', 'fields'].detect { |k| r.key?(k) }
         | 
| 23 | 
            +
                    doc = k.nil? ? Hashie::Mash.new : r[k]
         | 
| 24 | 
            +
                    doc.merge({"_id" => r['_id']})
         | 
| 25 | 
            +
                  end
         | 
| 24 26 | 
             
                end
         | 
| 25 27 | 
             
              end
         | 
| 26 28 | 
             
            end
         | 
    
        data/lib/stretcher/server.rb
    CHANGED
    
    | @@ -119,7 +119,7 @@ module Stretcher | |
| 119 119 | 
             
                    req.body = text
         | 
| 120 120 | 
             
                  end
         | 
| 121 121 | 
             
                end
         | 
| 122 | 
            -
             | 
| 122 | 
            +
             | 
| 123 123 | 
             
                # Perform a refresh, making all indexed documents available
         | 
| 124 124 | 
             
                def refresh
         | 
| 125 125 | 
             
                  do_refresh
         | 
| @@ -146,6 +146,10 @@ module Stretcher | |
| 146 146 |  | 
| 147 147 | 
             
                  if res.status >= 200 && res.status <= 299
         | 
| 148 148 | 
             
                    res.body
         | 
| 149 | 
            +
                  elsif res.status == 404
         | 
| 150 | 
            +
                    err_str = "Error 404 processing request: (#{res.status})! #{res.env[:method]} URL: #{res.env[:url]}"
         | 
| 151 | 
            +
                    err_str << "\n Resp Body: #{res.body}"
         | 
| 152 | 
            +
                    raise RequestError::NotFound.new(res), err_str
         | 
| 149 153 | 
             
                  else
         | 
| 150 154 | 
             
                    err_str = "Error processing request (#{res.status})! #{res.env[:method]} URL: #{res.env[:url]}"
         | 
| 151 155 | 
             
                    err_str << "\n Resp Body: #{res.body}"
         | 
    
        data/lib/stretcher/util.rb
    CHANGED
    
    
    
        data/lib/stretcher/version.rb
    CHANGED
    
    
| @@ -4,7 +4,16 @@ describe Stretcher::Index do | |
| 4 4 | 
             
              let(:server) {
         | 
| 5 5 | 
             
                Stretcher::Server.new(ES_URL, :logger => DEBUG_LOGGER)
         | 
| 6 6 | 
             
              }
         | 
| 7 | 
            -
              let(:index) { | 
| 7 | 
            +
              let(:index) {
         | 
| 8 | 
            +
                i = server.index('foo')
         | 
| 9 | 
            +
                i.delete
         | 
| 10 | 
            +
                server.refresh
         | 
| 11 | 
            +
                i.create
         | 
| 12 | 
            +
                # Why do both? Doesn't hurt, and it fixes some races
         | 
| 13 | 
            +
                server.refresh
         | 
| 14 | 
            +
                i.refresh
         | 
| 15 | 
            +
                i
         | 
| 16 | 
            +
              }
         | 
| 8 17 | 
             
              let(:corpus) {
         | 
| 9 18 | 
             
                [
         | 
| 10 19 | 
             
                 {:text => "Foo", "_type" => 'tweet', "_id" => 'fooid'},
         | 
| @@ -21,6 +30,7 @@ describe Stretcher::Index do | |
| 21 30 | 
             
              def seed_corpus
         | 
| 22 31 | 
             
                create_tweet_mapping
         | 
| 23 32 | 
             
                index.bulk_index(corpus)
         | 
| 33 | 
            +
                index.refresh
         | 
| 24 34 | 
             
              end
         | 
| 25 35 |  | 
| 26 36 | 
             
              it "should work on an existential level" do
         | 
| @@ -63,6 +73,14 @@ describe Stretcher::Index do | |
| 63 73 | 
             
                }
         | 
| 64 74 | 
             
              end
         | 
| 65 75 |  | 
| 76 | 
            +
              it "should delete by query" do
         | 
| 77 | 
            +
                seed_corpus
         | 
| 78 | 
            +
                index.search(:query => {:match_all => {}}).total == 3
         | 
| 79 | 
            +
                index.delete_query(:match_all => {})
         | 
| 80 | 
            +
                index.refresh
         | 
| 81 | 
            +
                index.search(:query => {:match_all => {}}).total == 0
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
             | 
| 66 84 | 
             
              it "should search without error" do
         | 
| 67 85 | 
             
                seed_corpus
         | 
| 68 86 | 
             
                match_text = corpus.first[:text]
         | 
| @@ -80,7 +98,7 @@ describe Stretcher::Index do | |
| 80 98 | 
             
              end
         | 
| 81 99 |  | 
| 82 100 | 
             
              it "execute the analysis API and return an expected result" do
         | 
| 83 | 
            -
                analyzed = index.analyze("Candles", :analyzer => :snowball)
         | 
| 101 | 
            +
                analyzed = server.index(:foo).analyze("Candles", :analyzer => :snowball)
         | 
| 84 102 | 
             
                analyzed.tokens.first.token.should == 'candl'
         | 
| 85 103 | 
             
              end
         | 
| 86 104 |  | 
| @@ -1,29 +1,38 @@ | |
| 1 1 | 
             
            require 'spec_helper'
         | 
| 2 2 |  | 
| 3 | 
            -
            describe Stretcher:: | 
| 3 | 
            +
            describe Stretcher::IndexType do
         | 
| 4 4 | 
             
              let(:server) { Stretcher::Server.new(ES_URL) }
         | 
| 5 | 
            -
              let(:index) { | 
| 6 | 
            -
             | 
| 5 | 
            +
              let(:index) {
         | 
| 6 | 
            +
                i = server.index(:foo)
         | 
| 7 | 
            +
                i
         | 
| 8 | 
            +
              }
         | 
| 9 | 
            +
              let(:type) {
         | 
| 10 | 
            +
                t = index.type(:bar)
         | 
| 11 | 
            +
                t.delete_query(:match_all => {})
         | 
| 12 | 
            +
                index.refresh
         | 
| 13 | 
            +
                mapping = {"bar" => {"properties" => {"message" => {"type" => "string"}}}}
         | 
| 14 | 
            +
                t.put_mapping mapping
         | 
| 15 | 
            +
                t
         | 
| 16 | 
            +
              }
         | 
| 7 17 |  | 
| 8 18 | 
             
              it "should be existentially aware" do
         | 
| 9 | 
            -
                 | 
| 10 | 
            -
                 | 
| 11 | 
            -
                mapping = {" | 
| 12 | 
            -
                 | 
| 13 | 
            -
                 | 
| 14 | 
            -
                 | 
| 19 | 
            +
                t = index.type(:existential)
         | 
| 20 | 
            +
                t.exists?.should be_false
         | 
| 21 | 
            +
                mapping = {"existential" => {"properties" => {"message" => {"type" => "string"}}}}
         | 
| 22 | 
            +
                t.put_mapping mapping
         | 
| 23 | 
            +
                t.exists?.should be_true
         | 
| 24 | 
            +
                t.get_mapping.should == mapping
         | 
| 15 25 | 
             
              end
         | 
| 16 26 |  | 
| 17 27 | 
             
              describe "searching" do
         | 
| 18 28 | 
             
                before do
         | 
| 19 29 | 
             
                  @doc = {:message => "hello"}
         | 
| 30 | 
            +
                  type.put(123123, @doc)
         | 
| 31 | 
            +
                  index.refresh
         | 
| 20 32 | 
             
                end
         | 
| 21 33 |  | 
| 22 34 | 
             
                it "should search and find the right doc" do
         | 
| 23 | 
            -
                   | 
| 24 | 
            -
                  type.put(123123, @doc)
         | 
| 25 | 
            -
                  index.refresh
         | 
| 26 | 
            -
                  res = type.search({}, {:query => {:match => {:message => match_text}}})
         | 
| 35 | 
            +
                  res = type.search({}, {:query => {:match => {:message => @doc[:message]}}})
         | 
| 27 36 | 
             
                  res.results.first.message.should == @doc[:message]
         | 
| 28 37 | 
             
                end
         | 
| 29 38 |  | 
| @@ -31,21 +40,37 @@ describe Stretcher::Index do | |
| 31 40 | 
             
                  res = type.search({}, {query: {match_all: {}}, fields: ['message']})
         | 
| 32 41 | 
             
                  res.results.first.message.should == @doc[:message]
         | 
| 33 42 | 
             
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                it "should build results when no document fields are selected" do
         | 
| 45 | 
            +
                  res = type.search({}, {query: {match_all: {}}, fields: ['_id']})
         | 
| 46 | 
            +
                  res.results.first.should have_key '_id'
         | 
| 47 | 
            +
                end
         | 
| 34 48 | 
             
              end
         | 
| 35 49 |  | 
| 36 | 
            -
              describe "put/get" do
         | 
| 50 | 
            +
              describe "put/get/delete" do
         | 
| 37 51 | 
             
                before do
         | 
| 38 52 | 
             
                  @doc = {:message => "hello!"}
         | 
| 53 | 
            +
                  @put_res = type.put(987, @doc)
         | 
| 39 54 | 
             
                end
         | 
| 40 55 |  | 
| 41 56 | 
             
                it "should put correctly" do
         | 
| 42 | 
            -
                   | 
| 57 | 
            +
                  @put_res.should_not be_nil
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                it "should post correctly" do
         | 
| 61 | 
            +
                  type.post(@doc).should_not be_nil
         | 
| 43 62 | 
             
                end
         | 
| 44 63 |  | 
| 45 64 | 
             
                it "should get individual documents correctly" do
         | 
| 46 65 | 
             
                  type.get(987).message.should == @doc[:message]
         | 
| 47 66 | 
             
                end
         | 
| 48 67 |  | 
| 68 | 
            +
                it "should return nil when retrieving non-extant docs" do
         | 
| 69 | 
            +
                  lambda {
         | 
| 70 | 
            +
                    type.get(898323329)
         | 
| 71 | 
            +
                  }.should raise_exception(Stretcher::RequestError::NotFound)
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 49 74 | 
             
                it "should get individual raw documents correctly" do
         | 
| 50 75 | 
             
                  res = type.get(987, true)
         | 
| 51 76 | 
             
                  res["_id"].should == "987"
         | 
| @@ -57,6 +82,12 @@ describe Stretcher::Index do | |
| 57 82 | 
             
                  type.get(987).message.should == 'Updated!'
         | 
| 58 83 | 
             
                end
         | 
| 59 84 |  | 
| 85 | 
            +
                it "should delete by query correctly" do
         | 
| 86 | 
            +
                  type.delete_query("match_all" => {})
         | 
| 87 | 
            +
                  index.refresh
         | 
| 88 | 
            +
                  type.exists?(987).should be_false
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
             | 
| 60 91 | 
             
                it "should delete individual docs correctly" do
         | 
| 61 92 | 
             
                  type.exists?(987).should be_true
         | 
| 62 93 | 
             
                  type.delete(987)
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: stretcher
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.5.0
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2013-03- | 
| 12 | 
            +
            date: 2013-03-07 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: faraday
         |