typesense 0.6.0 → 0.8.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.
- checksums.yaml +4 -4
 - data/README.md +3 -1
 - data/examples/client_initialization.rb +16 -16
 - data/examples/collections_and_documents.rb +53 -8
 - data/lib/typesense/api_call.rb +37 -65
 - data/lib/typesense/document.rb +4 -0
 - data/lib/typesense/documents.rb +33 -6
 - data/lib/typesense/version.rb +1 -1
 - metadata +5 -5
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 5acfb1b3cbcfd880a7d8fa39a759ad2cb82396e159cdac02d64e72a4047ca264
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 1e6d7ca55d559a86842e79e4ffb4db18327206e78c45ff039ff2a8fa59822a7b
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 9fa4e3d1155043c18f873ee936eb5bf223d7faac05f99d311afaab9dd49faf2ba9088cf274c6c7402742422d951900f52626480f139949b6ad25e2245ba2f287
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: fe7fe260705cab7bf02dd0ebf28395860ce27a047e7ff8687c4fed5cbc4baf8aa4f79be4fb2ba08897b0f50eaa6861a9d9b9f4a7647ad959a8387c563b1c1c69
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -25,7 +25,7 @@ Or install it yourself as: 
     | 
|
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
            You'll find detailed documentation here: [https://typesense.org/api/](https://typesense.org/api/)
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
            Here are some examples that  
     | 
| 
      
 28 
     | 
    
         
            +
            Here are some examples with inline comments that walk you through how to use the Ruby client: [examples](examples)
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
30 
     | 
    
         
             
            Tests are also a good place to know how the the library works internally: [spec](spec)
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
         @@ -33,6 +33,8 @@ Tests are also a good place to know how the the library works internally: [spec] 
     | 
|
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
            | Typesense Server | typesense-ruby |
         
     | 
| 
       35 
35 
     | 
    
         
             
            |------------------|----------------|
         
     | 
| 
      
 36 
     | 
    
         
            +
            | \>= v0.16.0 | \>= v0.8.0 |
         
     | 
| 
      
 37 
     | 
    
         
            +
            | \>= v0.15.0 | \>= v0.7.0 |
         
     | 
| 
       36 
38 
     | 
    
         
             
            | \>= v0.12.1 | \>= v0.5.0 |
         
     | 
| 
       37 
39 
     | 
    
         
             
            | \>= v0.12.0 | \>= v0.4.0 |
         
     | 
| 
       38 
40 
     | 
    
         
             
            | <= v0.11 | <= v0.3.0 |
         
     | 
| 
         @@ -38,26 +38,26 @@ AwesomePrint.defaults = { 
     | 
|
| 
       38 
38 
     | 
    
         
             
                  host: 'localhost',
         
     | 
| 
       39 
39 
     | 
    
         
             
                  port: 8108,
         
     | 
| 
       40 
40 
     | 
    
         
             
                  protocol: 'http'
         
     | 
| 
       41 
     | 
    
         
            -
                },
         
     | 
| 
       42 
     | 
    
         
            -
                # Uncomment if starting a 3-node cluster, using Option 2 under Setup instructions above
         
     | 
| 
       43 
     | 
    
         
            -
                {
         
     | 
| 
       44 
     | 
    
         
            -
                  host: 'localhost',
         
     | 
| 
       45 
     | 
    
         
            -
                  port: 7108,
         
     | 
| 
       46 
     | 
    
         
            -
                  protocol: 'http'
         
     | 
| 
       47 
     | 
    
         
            -
                },
         
     | 
| 
       48 
     | 
    
         
            -
                {
         
     | 
| 
       49 
     | 
    
         
            -
                  host: 'localhost',
         
     | 
| 
       50 
     | 
    
         
            -
                  port: 9108,
         
     | 
| 
       51 
     | 
    
         
            -
                  protocol: 'http'
         
     | 
| 
       52 
41 
     | 
    
         
             
                }
         
     | 
| 
      
 42 
     | 
    
         
            +
                # Uncomment if starting a 3-node cluster, using Option 2 under Setup instructions above
         
     | 
| 
      
 43 
     | 
    
         
            +
                # {
         
     | 
| 
      
 44 
     | 
    
         
            +
                #   host: 'localhost',
         
     | 
| 
      
 45 
     | 
    
         
            +
                #   port: 7108,
         
     | 
| 
      
 46 
     | 
    
         
            +
                #   protocol: 'http'
         
     | 
| 
      
 47 
     | 
    
         
            +
                # },
         
     | 
| 
      
 48 
     | 
    
         
            +
                # {
         
     | 
| 
      
 49 
     | 
    
         
            +
                #   host: 'localhost',
         
     | 
| 
      
 50 
     | 
    
         
            +
                #   port: 9108,
         
     | 
| 
      
 51 
     | 
    
         
            +
                #   protocol: 'http'
         
     | 
| 
      
 52 
     | 
    
         
            +
                # }
         
     | 
| 
       53 
53 
     | 
    
         
             
              ],
         
     | 
| 
       54 
54 
     | 
    
         
             
              # If this optional key is specified, requests are always sent to this node first if it is healthy
         
     | 
| 
       55 
55 
     | 
    
         
             
              #   before falling back on the nodes mentioned in the `nodes` key. This is useful when running a distributed set of search clusters.
         
     | 
| 
       56 
     | 
    
         
            -
              'nearest_node': {
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
              },
         
     | 
| 
      
 56 
     | 
    
         
            +
              # 'nearest_node': {
         
     | 
| 
      
 57 
     | 
    
         
            +
              #   'host': 'localhost',
         
     | 
| 
      
 58 
     | 
    
         
            +
              #   'port': '8108',
         
     | 
| 
      
 59 
     | 
    
         
            +
              #   'protocol': 'http'
         
     | 
| 
      
 60 
     | 
    
         
            +
              # },
         
     | 
| 
       61 
61 
     | 
    
         
             
              api_key: 'xyz',
         
     | 
| 
       62 
62 
     | 
    
         
             
              num_retries: 10,
         
     | 
| 
       63 
63 
     | 
    
         
             
              healthcheck_interval_seconds: 1,
         
     | 
| 
         @@ -167,6 +167,10 @@ ap document 
     | 
|
| 
       167 
167 
     | 
    
         
             
            #   "num_employees" => 5215
         
     | 
| 
       168 
168 
     | 
    
         
             
            # }
         
     | 
| 
       169 
169 
     | 
    
         | 
| 
      
 170 
     | 
    
         
            +
            # You can also upsert a document, which will update the document if it already exists or create a new one if it doesn't exist
         
     | 
| 
      
 171 
     | 
    
         
            +
            document = @typesense.collections['companies'].documents.upsert(document)
         
     | 
| 
      
 172 
     | 
    
         
            +
            ap document
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
       170 
174 
     | 
    
         
             
            ##
         
     | 
| 
       171 
175 
     | 
    
         
             
            # Retrieve a document
         
     | 
| 
       172 
176 
     | 
    
         
             
            sleep 0.5 # Give Typesense cluster a few hundred ms to create the document on all nodes, before reading it right after (eventually consistent)
         
     | 
| 
         @@ -180,6 +184,25 @@ ap document 
     | 
|
| 
       180 
184 
     | 
    
         
             
            #   "num_employees" => 5215
         
     | 
| 
       181 
185 
     | 
    
         
             
            # }
         
     | 
| 
       182 
186 
     | 
    
         | 
| 
      
 187 
     | 
    
         
            +
            ##
         
     | 
| 
      
 188 
     | 
    
         
            +
            # Update a document. Unlike upsert, update will error out if the doc doesn't already exist.
         
     | 
| 
      
 189 
     | 
    
         
            +
            document = @typesense.collections['companies'].documents['124'].update(
         
     | 
| 
      
 190 
     | 
    
         
            +
              'id' => 1,
         
     | 
| 
      
 191 
     | 
    
         
            +
              'num_employees' => 5500
         
     | 
| 
      
 192 
     | 
    
         
            +
            )
         
     | 
| 
      
 193 
     | 
    
         
            +
            ap document
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
            # {
         
     | 
| 
      
 196 
     | 
    
         
            +
            #   "id"            => "124",
         
     | 
| 
      
 197 
     | 
    
         
            +
            #   "num_employees" => 5500
         
     | 
| 
      
 198 
     | 
    
         
            +
            # }
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
            # This should error out, since document 145 doesn't exist
         
     | 
| 
      
 201 
     | 
    
         
            +
            # document = @typesense.collections['companies'].documents['145'].update(
         
     | 
| 
      
 202 
     | 
    
         
            +
            #   'num_employees' => 5500
         
     | 
| 
      
 203 
     | 
    
         
            +
            # )
         
     | 
| 
      
 204 
     | 
    
         
            +
            # ap document
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
       183 
206 
     | 
    
         
             
            ##
         
     | 
| 
       184 
207 
     | 
    
         
             
            # Delete a document
         
     | 
| 
       185 
208 
     | 
    
         
             
            #   Deleting a document, returns the document after deletion
         
     | 
| 
         @@ -208,19 +231,41 @@ documents = [ 
     | 
|
| 
       208 
231 
     | 
    
         
             
                'country' => 'France'
         
     | 
| 
       209 
232 
     | 
    
         
             
              }
         
     | 
| 
       210 
233 
     | 
    
         
             
            ]
         
     | 
| 
       211 
     | 
    
         
            -
            ap @typesense.collections['companies'].documents. 
     | 
| 
      
 234 
     | 
    
         
            +
            ap @typesense.collections['companies'].documents.import(documents)
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
            ## If you already have documents in JSONL format, you can also pass it directly to #import, to avoid the JSON parsing overhead:
         
     | 
| 
      
 237 
     | 
    
         
            +
            # @typesense.collections['companies'].documents.import(documents_in_jsonl_format)
         
     | 
| 
      
 238 
     | 
    
         
            +
             
     | 
| 
      
 239 
     | 
    
         
            +
            ## You can bulk upsert documents, by adding an upsert action option to #import
         
     | 
| 
      
 240 
     | 
    
         
            +
            documents << {
         
     | 
| 
      
 241 
     | 
    
         
            +
              'id' => '126',
         
     | 
| 
      
 242 
     | 
    
         
            +
              'company_name' => 'Stark Industries 2',
         
     | 
| 
      
 243 
     | 
    
         
            +
              'num_employees' => 200,
         
     | 
| 
      
 244 
     | 
    
         
            +
              'country' => 'USA'
         
     | 
| 
      
 245 
     | 
    
         
            +
            }
         
     | 
| 
      
 246 
     | 
    
         
            +
            ap @typesense.collections['companies'].documents.import(documents, action: :upsert)
         
     | 
| 
      
 247 
     | 
    
         
            +
             
     | 
| 
      
 248 
     | 
    
         
            +
            ## You can bulk update documents, by adding an update action option to #import
         
     | 
| 
      
 249 
     | 
    
         
            +
            # `action: update` will throw an error if the document doesn't already exist
         
     | 
| 
      
 250 
     | 
    
         
            +
            # This document will error out, since id: 1200 doesn't exist
         
     | 
| 
      
 251 
     | 
    
         
            +
            documents << {
         
     | 
| 
      
 252 
     | 
    
         
            +
              'id' => '1200',
         
     | 
| 
      
 253 
     | 
    
         
            +
              'country' => 'USA'
         
     | 
| 
      
 254 
     | 
    
         
            +
            }
         
     | 
| 
      
 255 
     | 
    
         
            +
            documents << {
         
     | 
| 
      
 256 
     | 
    
         
            +
              'id' => '126',
         
     | 
| 
      
 257 
     | 
    
         
            +
              'num_employees' => 300
         
     | 
| 
      
 258 
     | 
    
         
            +
            }
         
     | 
| 
      
 259 
     | 
    
         
            +
            ap @typesense.collections['companies'].documents.import(documents, action: :update)
         
     | 
| 
       212 
260 
     | 
    
         | 
| 
       213 
261 
     | 
    
         
             
            ##
         
     | 
| 
       214 
262 
     | 
    
         
             
            # Export all documents in a collection in JSON Lines format
         
     | 
| 
       215 
     | 
    
         
            -
            #   We use JSON Lines format for performance reasons. You can choose to parse selected lines  
     | 
| 
      
 263 
     | 
    
         
            +
            #   We use JSON Lines format for performance reasons. You can choose to parse selected lines as needed, by splitting on \n.
         
     | 
| 
       216 
264 
     | 
    
         
             
            sleep 0.5 # Give Typesense cluster a few hundred ms to create the document on all nodes, before reading it right after (eventually consistent)
         
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
            ap  
     | 
| 
      
 265 
     | 
    
         
            +
            jsonl_data = @typesense.collections['companies'].documents.export
         
     | 
| 
      
 266 
     | 
    
         
            +
            ap jsonl_data
         
     | 
| 
       219 
267 
     | 
    
         | 
| 
       220 
     | 
    
         
            -
            #  
     | 
| 
       221 
     | 
    
         
            -
            # [0] "{\"company_name\":\"Stark Industries\",\"country\":\"USA\",\"id\":\"124\",\"num_employees\":5215}",
         
     | 
| 
       222 
     | 
    
         
            -
            # [1] "{\"company_name\":\"Acme Corp\",\"country\":\"France\",\"id\":\"125\",\"num_employees\":1002}"
         
     | 
| 
       223 
     | 
    
         
            -
            # ]
         
     | 
| 
      
 268 
     | 
    
         
            +
            # "{\"company_name\":\"Stark Industries\",\"country\":\"USA\",\"id\":\"124\",\"num_employees\":5215}\n{\"company_name\":\"Acme Corp\",\"country\":\"France\",\"id\":\"125\",\"num_employees\":1002}"
         
     | 
| 
       224 
269 
     | 
    
         | 
| 
       225 
270 
     | 
    
         
             
            ##
         
     | 
| 
       226 
271 
     | 
    
         
             
            # Cleanup
         
     | 
    
        data/lib/typesense/api_call.rb
    CHANGED
    
    | 
         @@ -7,6 +7,8 @@ module Typesense 
     | 
|
| 
       7 
7 
     | 
    
         
             
              class ApiCall
         
     | 
| 
       8 
8 
     | 
    
         
             
                API_KEY_HEADER_NAME = 'X-TYPESENSE-API-KEY'
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
      
 10 
     | 
    
         
            +
                attr_reader :logger
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       10 
12 
     | 
    
         
             
                def initialize(configuration)
         
     | 
| 
       11 
13 
     | 
    
         
             
                  @configuration = configuration
         
     | 
| 
       12 
14 
     | 
    
         | 
| 
         @@ -24,43 +26,40 @@ module Typesense 
     | 
|
| 
       24 
26 
     | 
    
         
             
                  @current_node_index = -1
         
     | 
| 
       25 
27 
     | 
    
         
             
                end
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                def post(endpoint,  
     | 
| 
       28 
     | 
    
         
            -
                  headers, body = extract_headers_and_body_from(parameters)
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
                def post(endpoint, body_parameters = {}, query_parameters = {})
         
     | 
| 
       30 
30 
     | 
    
         
             
                  perform_request :post,
         
     | 
| 
       31 
31 
     | 
    
         
             
                                  endpoint,
         
     | 
| 
       32 
     | 
    
         
            -
                                   
     | 
| 
       33 
     | 
    
         
            -
                                   
     | 
| 
      
 32 
     | 
    
         
            +
                                  query_parameters: query_parameters,
         
     | 
| 
      
 33 
     | 
    
         
            +
                                  body_parameters: body_parameters
         
     | 
| 
       34 
34 
     | 
    
         
             
                end
         
     | 
| 
       35 
35 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                def  
     | 
| 
       37 
     | 
    
         
            -
                   
     | 
| 
      
 36 
     | 
    
         
            +
                def patch(endpoint, body_parameters = {}, query_parameters = {})
         
     | 
| 
      
 37 
     | 
    
         
            +
                  perform_request :patch,
         
     | 
| 
      
 38 
     | 
    
         
            +
                                  endpoint,
         
     | 
| 
      
 39 
     | 
    
         
            +
                                  query_parameters: query_parameters,
         
     | 
| 
      
 40 
     | 
    
         
            +
                                  body_parameters: body_parameters
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
       38 
42 
     | 
    
         | 
| 
      
 43 
     | 
    
         
            +
                def put(endpoint, body_parameters = {}, query_parameters = {})
         
     | 
| 
       39 
44 
     | 
    
         
             
                  perform_request :put,
         
     | 
| 
       40 
45 
     | 
    
         
             
                                  endpoint,
         
     | 
| 
       41 
     | 
    
         
            -
                                   
     | 
| 
       42 
     | 
    
         
            -
                                   
     | 
| 
      
 46 
     | 
    
         
            +
                                  query_parameters: query_parameters,
         
     | 
| 
      
 47 
     | 
    
         
            +
                                  body_parameters: body_parameters
         
     | 
| 
       43 
48 
     | 
    
         
             
                end
         
     | 
| 
       44 
49 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                def get(endpoint,  
     | 
| 
       46 
     | 
    
         
            -
                  headers, query = extract_headers_and_query_from(parameters)
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
      
 50 
     | 
    
         
            +
                def get(endpoint, query_parameters = {})
         
     | 
| 
       48 
51 
     | 
    
         
             
                  perform_request :get,
         
     | 
| 
       49 
52 
     | 
    
         
             
                                  endpoint,
         
     | 
| 
       50 
     | 
    
         
            -
                                   
     | 
| 
       51 
     | 
    
         
            -
                                  params: query
         
     | 
| 
      
 53 
     | 
    
         
            +
                                  query_parameters: query_parameters
         
     | 
| 
       52 
54 
     | 
    
         
             
                end
         
     | 
| 
       53 
55 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
                def delete(endpoint,  
     | 
| 
       55 
     | 
    
         
            -
                  headers, query = extract_headers_and_query_from(parameters)
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 56 
     | 
    
         
            +
                def delete(endpoint, query_parameters = {})
         
     | 
| 
       57 
57 
     | 
    
         
             
                  perform_request :delete,
         
     | 
| 
       58 
58 
     | 
    
         
             
                                  endpoint,
         
     | 
| 
       59 
     | 
    
         
            -
                                   
     | 
| 
       60 
     | 
    
         
            -
                                  params: query
         
     | 
| 
      
 59 
     | 
    
         
            +
                                  query_parameters: query_parameters
         
     | 
| 
       61 
60 
     | 
    
         
             
                end
         
     | 
| 
       62 
61 
     | 
    
         | 
| 
       63 
     | 
    
         
            -
                def perform_request(method, endpoint,  
     | 
| 
      
 62 
     | 
    
         
            +
                def perform_request(method, endpoint, query_parameters: nil, body_parameters: nil, additional_headers: {})
         
     | 
| 
       64 
63 
     | 
    
         
             
                  @configuration.validate!
         
     | 
| 
       65 
64 
     | 
    
         
             
                  last_exception = nil
         
     | 
| 
       66 
65 
     | 
    
         
             
                  @logger.debug "Performing #{method.to_s.upcase} request: #{endpoint}"
         
     | 
| 
         @@ -70,15 +69,23 @@ module Typesense 
     | 
|
| 
       70 
69 
     | 
    
         
             
                    @logger.debug "Attempting #{method.to_s.upcase} request Try ##{num_tries} to Node #{node[:index]}"
         
     | 
| 
       71 
70 
     | 
    
         | 
| 
       72 
71 
     | 
    
         
             
                    begin
         
     | 
| 
       73 
     | 
    
         
            -
                       
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
      
 72 
     | 
    
         
            +
                      request_options = {
         
     | 
| 
      
 73 
     | 
    
         
            +
                        method: method,
         
     | 
| 
      
 74 
     | 
    
         
            +
                        timeout: @connection_timeout_seconds,
         
     | 
| 
      
 75 
     | 
    
         
            +
                        headers: default_headers.merge(additional_headers)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      }
         
     | 
| 
      
 77 
     | 
    
         
            +
                      request_options.merge!(params: query_parameters) unless query_parameters.nil?
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                      unless body_parameters.nil?
         
     | 
| 
      
 80 
     | 
    
         
            +
                        body = body_parameters
         
     | 
| 
      
 81 
     | 
    
         
            +
                        body = Oj.dump(body_parameters) if request_options[:headers]['Content-Type'] == 'application/json'
         
     | 
| 
      
 82 
     | 
    
         
            +
                        request_options.merge!(body: body)
         
     | 
| 
      
 83 
     | 
    
         
            +
                      end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                      response = Typhoeus::Request.new(uri_for(endpoint, node), request_options).run
         
     | 
| 
       79 
86 
     | 
    
         
             
                      set_node_healthcheck(node, is_healthy: true) if response.code >= 1 && response.code <= 499
         
     | 
| 
       80 
87 
     | 
    
         | 
| 
       81 
     | 
    
         
            -
                      @logger.debug "Request to Node #{node[:index]} was successfully made (at the network layer). Response Code was #{response.code}."
         
     | 
| 
      
 88 
     | 
    
         
            +
                      @logger.debug "Request #{method}:#{uri_for(endpoint, node)} to Node #{node[:index]} was successfully made (at the network layer). Response Code was #{response.code}."
         
     | 
| 
       82 
89 
     | 
    
         | 
| 
       83 
90 
     | 
    
         
             
                      parsed_response = if response.headers && (response.headers['content-type'] || '').include?('application/json')
         
     | 
| 
       84 
91 
     | 
    
         
             
                                          Oj.load(response.body)
         
     | 
| 
         @@ -91,8 +98,7 @@ module Typesense 
     | 
|
| 
       91 
98 
     | 
    
         | 
| 
       92 
99 
     | 
    
         
             
                      exception_message = (parsed_response && parsed_response['message']) || 'Error'
         
     | 
| 
       93 
100 
     | 
    
         
             
                      raise custom_exception_klass_for(response), exception_message
         
     | 
| 
       94 
     | 
    
         
            -
                    rescue  
     | 
| 
       95 
     | 
    
         
            -
                           Errno::EINVAL, Errno::ENETDOWN, Errno::ENETUNREACH, Errno::ENETRESET, Errno::ECONNABORTED, Errno::ECONNRESET,
         
     | 
| 
      
 101 
     | 
    
         
            +
                    rescue Errno::EINVAL, Errno::ENETDOWN, Errno::ENETUNREACH, Errno::ENETRESET, Errno::ECONNABORTED, Errno::ECONNRESET,
         
     | 
| 
       96 
102 
     | 
    
         
             
                           Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::EHOSTDOWN, Errno::EHOSTUNREACH,
         
     | 
| 
       97 
103 
     | 
    
         
             
                           Typesense::Error::TimeoutError, Typesense::Error::ServerError, Typesense::Error::HTTPStatus0Error => e
         
     | 
| 
       98 
104 
     | 
    
         
             
                      # Rescue network layer exceptions and HTTP 5xx errors, so the loop can continue.
         
     | 
| 
         @@ -100,7 +106,7 @@ module Typesense 
     | 
|
| 
       100 
106 
     | 
    
         
             
                      #   other languages that might not support the same construct.
         
     | 
| 
       101 
107 
     | 
    
         
             
                      set_node_healthcheck(node, is_healthy: false)
         
     | 
| 
       102 
108 
     | 
    
         
             
                      last_exception = e
         
     | 
| 
       103 
     | 
    
         
            -
                      @logger.warn "Request to Node #{node[:index]} failed due to \"#{e.class}: #{e.message}\""
         
     | 
| 
      
 109 
     | 
    
         
            +
                      @logger.warn "Request #{method}:#{uri_for(endpoint, node)} to Node #{node[:index]} failed due to \"#{e.class}: #{e.message}\""
         
     | 
| 
       104 
110 
     | 
    
         
             
                      @logger.warn "Sleeping for #{@retry_interval_seconds}s and then retrying request..."
         
     | 
| 
       105 
111 
     | 
    
         
             
                      sleep @retry_interval_seconds
         
     | 
| 
       106 
112 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -111,41 +117,6 @@ module Typesense 
     | 
|
| 
       111 
117 
     | 
    
         | 
| 
       112 
118 
     | 
    
         
             
                private
         
     | 
| 
       113 
119 
     | 
    
         | 
| 
       114 
     | 
    
         
            -
                def extract_headers_and_body_from(parameters)
         
     | 
| 
       115 
     | 
    
         
            -
                  if json_request?(parameters)
         
     | 
| 
       116 
     | 
    
         
            -
                    headers = { 'Content-Type' => 'application/json' }
         
     | 
| 
       117 
     | 
    
         
            -
                    body = Oj.dump(sanitize_parameters(parameters))
         
     | 
| 
       118 
     | 
    
         
            -
                  else
         
     | 
| 
       119 
     | 
    
         
            -
                    headers = {}
         
     | 
| 
       120 
     | 
    
         
            -
                    body = parameters[:body]
         
     | 
| 
       121 
     | 
    
         
            -
                  end
         
     | 
| 
       122 
     | 
    
         
            -
                  [headers, body]
         
     | 
| 
       123 
     | 
    
         
            -
                end
         
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
                def extract_headers_and_query_from(parameters)
         
     | 
| 
       126 
     | 
    
         
            -
                  if json_request?(parameters)
         
     | 
| 
       127 
     | 
    
         
            -
                    headers = { 'Content-Type' => 'application/json' }
         
     | 
| 
       128 
     | 
    
         
            -
                    query = sanitize_parameters(parameters)
         
     | 
| 
       129 
     | 
    
         
            -
                  else
         
     | 
| 
       130 
     | 
    
         
            -
                    headers = {}
         
     | 
| 
       131 
     | 
    
         
            -
                    query = parameters[:query]
         
     | 
| 
       132 
     | 
    
         
            -
                  end
         
     | 
| 
       133 
     | 
    
         
            -
                  [headers, query]
         
     | 
| 
       134 
     | 
    
         
            -
                end
         
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
                def json_request?(parameters)
         
     | 
| 
       137 
     | 
    
         
            -
                  parameters[:as_json].nil? ? true : parameters[:as_json]
         
     | 
| 
       138 
     | 
    
         
            -
                end
         
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
                def sanitize_parameters(parameters)
         
     | 
| 
       141 
     | 
    
         
            -
                  sanitized_parameters = parameters.dup
         
     | 
| 
       142 
     | 
    
         
            -
                  sanitized_parameters.delete(:as_json)
         
     | 
| 
       143 
     | 
    
         
            -
                  sanitized_parameters.delete(:body)
         
     | 
| 
       144 
     | 
    
         
            -
                  sanitized_parameters.delete(:query)
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
                  sanitized_parameters
         
     | 
| 
       147 
     | 
    
         
            -
                end
         
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
       149 
120 
     | 
    
         
             
                def uri_for(endpoint, node)
         
     | 
| 
       150 
121 
     | 
    
         
             
                  "#{node[:protocol]}://#{node[:host]}:#{node[:port]}#{endpoint}"
         
     | 
| 
       151 
122 
     | 
    
         
             
                end
         
     | 
| 
         @@ -228,6 +199,7 @@ module Typesense 
     | 
|
| 
       228 
199 
     | 
    
         | 
| 
       229 
200 
     | 
    
         
             
                def default_headers
         
     | 
| 
       230 
201 
     | 
    
         
             
                  {
         
     | 
| 
      
 202 
     | 
    
         
            +
                    'Content-Type' => 'application/json',
         
     | 
| 
       231 
203 
     | 
    
         
             
                    API_KEY_HEADER_NAME.to_s => @api_key,
         
     | 
| 
       232 
204 
     | 
    
         
             
                    'User-Agent' => 'Typesense Ruby Client'
         
     | 
| 
       233 
205 
     | 
    
         
             
                  }
         
     | 
    
        data/lib/typesense/document.rb
    CHANGED
    
    
    
        data/lib/typesense/documents.rb
    CHANGED
    
    | 
         @@ -16,17 +16,44 @@ module Typesense 
     | 
|
| 
       16 
16 
     | 
    
         
             
                  @api_call.post(endpoint_path, document)
         
     | 
| 
       17 
17 
     | 
    
         
             
                end
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                def  
     | 
| 
       20 
     | 
    
         
            -
                   
     | 
| 
       21 
     | 
    
         
            -
                  import(documents_in_jsonl_format)
         
     | 
| 
      
 19 
     | 
    
         
            +
                def upsert(document)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @api_call.post(endpoint_path, document, action: :upsert)
         
     | 
| 
       22 
21 
     | 
    
         
             
                end
         
     | 
| 
       23 
22 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
                def  
     | 
| 
       25 
     | 
    
         
            -
                  @api_call.post(endpoint_path 
     | 
| 
      
 23 
     | 
    
         
            +
                def update(document)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @api_call.post(endpoint_path, document, action: :update)
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def create_many(documents, options = {})
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @api_call.logger.warn('#create_many is deprecated and will be removed in a future version. Use #import instead, which now takes both an array of documents or a JSONL string of documents')
         
     | 
| 
      
 29 
     | 
    
         
            +
                  import(documents, options)
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                # @param [Array,String] documents An array of document hashes or a JSONL string of documents.
         
     | 
| 
      
 33 
     | 
    
         
            +
                def import(documents, options = {})
         
     | 
| 
      
 34 
     | 
    
         
            +
                  documents_in_jsonl_format = if documents.is_a?(Array)
         
     | 
| 
      
 35 
     | 
    
         
            +
                                                documents.map { |document| Oj.dump(document) }.join("\n")
         
     | 
| 
      
 36 
     | 
    
         
            +
                                              else
         
     | 
| 
      
 37 
     | 
    
         
            +
                                                documents
         
     | 
| 
      
 38 
     | 
    
         
            +
                                              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  results_in_jsonl_format = @api_call.perform_request(
         
     | 
| 
      
 41 
     | 
    
         
            +
                    'post',
         
     | 
| 
      
 42 
     | 
    
         
            +
                    endpoint_path('import'),
         
     | 
| 
      
 43 
     | 
    
         
            +
                    query_parameters: options,
         
     | 
| 
      
 44 
     | 
    
         
            +
                    body_parameters: documents_in_jsonl_format,
         
     | 
| 
      
 45 
     | 
    
         
            +
                    additional_headers: { 'Content-Type' => 'text/plain' }
         
     | 
| 
      
 46 
     | 
    
         
            +
                  )
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                  if documents.is_a?(Array)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    results_in_jsonl_format.split("\n").map { |r| Oj.load(r) }
         
     | 
| 
      
 50 
     | 
    
         
            +
                  else
         
     | 
| 
      
 51 
     | 
    
         
            +
                    results_in_jsonl_format
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
       26 
53 
     | 
    
         
             
                end
         
     | 
| 
       27 
54 
     | 
    
         | 
| 
       28 
55 
     | 
    
         
             
                def export
         
     | 
| 
       29 
     | 
    
         
            -
                   
     | 
| 
      
 56 
     | 
    
         
            +
                  @api_call.get(endpoint_path('export'))
         
     | 
| 
       30 
57 
     | 
    
         
             
                end
         
     | 
| 
       31 
58 
     | 
    
         | 
| 
       32 
59 
     | 
    
         
             
                def search(search_parameters)
         
     | 
    
        data/lib/typesense/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: typesense
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.8.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Typesense, Inc.
         
     | 
| 
       8 
     | 
    
         
            -
            autorequire: 
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: exe
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2020- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2020-10-25 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: awesome_print
         
     | 
| 
         @@ -298,7 +298,7 @@ homepage: https://typesense.org 
     | 
|
| 
       298 
298 
     | 
    
         
             
            licenses:
         
     | 
| 
       299 
299 
     | 
    
         
             
            - Apache-2.0
         
     | 
| 
       300 
300 
     | 
    
         
             
            metadata: {}
         
     | 
| 
       301 
     | 
    
         
            -
            post_install_message: 
     | 
| 
      
 301 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
       302 
302 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       303 
303 
     | 
    
         
             
            require_paths:
         
     | 
| 
       304 
304 
     | 
    
         
             
            - lib
         
     | 
| 
         @@ -314,7 +314,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       314 
314 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       315 
315 
     | 
    
         
             
            requirements: []
         
     | 
| 
       316 
316 
     | 
    
         
             
            rubygems_version: 3.0.6
         
     | 
| 
       317 
     | 
    
         
            -
            signing_key: 
     | 
| 
      
 317 
     | 
    
         
            +
            signing_key:
         
     | 
| 
       318 
318 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       319 
319 
     | 
    
         
             
            summary: Ruby Library for Typesense
         
     | 
| 
       320 
320 
     | 
    
         
             
            test_files: []
         
     |