elasticsearch_record 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.
- checksums.yaml +4 -4
 - data/README.md +177 -35
 - data/docs/CHANGELOG.md +12 -0
 - data/elasticsearch_record.gemspec +2 -2
 - data/lib/active_record/connection_adapters/elasticsearch/schema_statements.rb +8 -0
 - data/lib/elasticsearch_record/core.rb +15 -10
 - data/lib/elasticsearch_record/gem_version.rb +1 -1
 - data/lib/elasticsearch_record/model_api.rb +39 -4
 - data/lib/elasticsearch_record/relation/core_methods.rb +14 -6
 - data/lib/elasticsearch_record/relation/result_methods.rb +10 -5
 - data/lib/elasticsearch_record/relation/value_methods.rb +9 -0
 - metadata +8 -8
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 3f50568400141462093f5d91bf5b26efb44a52b9529577d5e72a4d3699a57717
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 89536ffacc4ddd5fb4d0334eda843d206c25fc867664f6f9454ee07d921ec712
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 20d82567d738f3f5fa78cdd1bb2595ea7cd068dd16a14fbda56b4c88450a33cac5b32106652401854e0085e1c4378cce6b3ef23983b04ec71fb14f931628c19e
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 3bcd72650c2d0817048edf3eff0be6ba8de4cc568b04203c3ec9631ccd4ef269b1c91f6f70d90dc05419357e5f4d3c3f164b4b4345f72c54c9d0cfabe15d3103
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -14,10 +14,8 @@ _ElasticsearchRecord is a ActiveRecord adapter and provides similar functionalit 
     | 
|
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
            **PLEASE NOTE:**
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
            -  
     | 
| 
       18 
     | 
    
         
            -
            -  
     | 
| 
       19 
     | 
    
         
            -
            - You might experience BUGs and Exceptions...
         
     | 
| 
       20 
     | 
    
         
            -
            - Currently supports only ActiveRecord 7.0 + Elasticsearch 8.4 _(downgrade for rails 6.x is planned in future versions)_
         
     | 
| 
      
 17 
     | 
    
         
            +
            - Specs & documentation are still missing, but will follow.
         
     | 
| 
      
 18 
     | 
    
         
            +
            - Currently supports ActiveRecord ~> 7.0 + Elasticsearch >= 7.17
         
     | 
| 
       21 
19 
     | 
    
         | 
| 
       22 
20 
     | 
    
         
             
            -----
         
     | 
| 
       23 
21 
     | 
    
         | 
| 
         @@ -63,7 +61,7 @@ Or install it yourself as: 
     | 
|
| 
       63 
61 
     | 
    
         | 
| 
       64 
62 
     | 
    
         
             
             development:
         
     | 
| 
       65 
63 
     | 
    
         
             
               primary:
         
     | 
| 
       66 
     | 
    
         
            -
             
     | 
| 
      
 64 
     | 
    
         
            +
                 # <...>
         
     | 
| 
       67 
65 
     | 
    
         | 
| 
       68 
66 
     | 
    
         
             
               # elasticsearch
         
     | 
| 
       69 
67 
     | 
    
         
             
               elasticsearch:
         
     | 
| 
         @@ -71,10 +69,24 @@ Or install it yourself as: 
     | 
|
| 
       71 
69 
     | 
    
         
             
                 host: localhost:9200
         
     | 
| 
       72 
70 
     | 
    
         
             
                 user: elastic
         
     | 
| 
       73 
71 
     | 
    
         
             
                 password: '****'
         
     | 
| 
       74 
     | 
    
         
            -
                  
     | 
| 
      
 72 
     | 
    
         
            +
                 
         
     | 
| 
      
 73 
     | 
    
         
            +
                 # enable ES verbose logging
         
     | 
| 
      
 74 
     | 
    
         
            +
                 # log: true
         
     | 
| 
      
 75 
     | 
    
         
            +
                 
         
     | 
| 
      
 76 
     | 
    
         
            +
                 # add table (index) prefix & suffix to all 'tables'
         
     | 
| 
      
 77 
     | 
    
         
            +
                 # table_name_prefix: 'app-'
         
     | 
| 
      
 78 
     | 
    
         
            +
                 # table_name_suffix: '-development'
         
     | 
| 
       75 
79 
     | 
    
         | 
| 
       76 
80 
     | 
    
         
             
             production:
         
     | 
| 
       77 
     | 
    
         
            -
                
     | 
| 
      
 81 
     | 
    
         
            +
               # <...>
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
               # elasticsearch
         
     | 
| 
      
 84 
     | 
    
         
            +
               elasticsearch:
         
     | 
| 
      
 85 
     | 
    
         
            +
                 # <...>
         
     | 
| 
      
 86 
     | 
    
         
            +
               
         
     | 
| 
      
 87 
     | 
    
         
            +
                 # add table (index) prefix & suffix to all 'tables'
         
     | 
| 
      
 88 
     | 
    
         
            +
                 # table_name_prefix: 'app-'
         
     | 
| 
      
 89 
     | 
    
         
            +
                 # table_name_suffix: '-production'
         
     | 
| 
       78 
90 
     | 
    
         | 
| 
       79 
91 
     | 
    
         
             
             test:
         
     | 
| 
       80 
92 
     | 
    
         
             
               ...
         
     | 
| 
         @@ -82,15 +94,19 @@ Or install it yourself as: 
     | 
|
| 
       82 
94 
     | 
    
         | 
| 
       83 
95 
     | 
    
         
             
            ```
         
     | 
| 
       84 
96 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
            ### b) Require  
     | 
| 
      
 97 
     | 
    
         
            +
            ### b) Require `elasticsearch_record/instrumentation` in your application.rb (if you want to...):
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
       86 
99 
     | 
    
         
             
            ```ruby
         
     | 
| 
       87 
100 
     | 
    
         
             
            # config/application.rb
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
       88 
102 
     | 
    
         
             
            require_relative "boot"
         
     | 
| 
       89 
103 
     | 
    
         | 
| 
       90 
104 
     | 
    
         
             
            require "rails"
         
     | 
| 
       91 
105 
     | 
    
         
             
            # Pick the frameworks you want:
         
     | 
| 
       92 
106 
     | 
    
         | 
| 
       93 
     | 
    
         
            -
            #  
     | 
| 
      
 107 
     | 
    
         
            +
            # <...>
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
            # add instrumentation
         
     | 
| 
       94 
110 
     | 
    
         
             
            require 'elasticsearch_record/instrumentation'
         
     | 
| 
       95 
111 
     | 
    
         | 
| 
       96 
112 
     | 
    
         
             
            module Application
         
     | 
| 
         @@ -98,14 +114,24 @@ module Application 
     | 
|
| 
       98 
114 
     | 
    
         
             
            end
         
     | 
| 
       99 
115 
     | 
    
         
             
            ```
         
     | 
| 
       100 
116 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
            ### c) Create a model that inherits from  
     | 
| 
      
 117 
     | 
    
         
            +
            ### c) Create a model that inherits from `ElasticsearchRecord::Base` model.
         
     | 
| 
       102 
118 
     | 
    
         
             
            ```ruby
         
     | 
| 
       103 
119 
     | 
    
         
             
            # app/models/application_elasticsearch_record.rb
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
            class  
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
            class ApplicationElasticsearchRecord < ElasticsearchRecord::Base
         
     | 
| 
      
 122 
     | 
    
         
            +
              # needs to be abstract
         
     | 
| 
      
 123 
     | 
    
         
            +
              self.abstract_class = true
         
     | 
| 
       107 
124 
     | 
    
         
             
            end
         
     | 
| 
      
 125 
     | 
    
         
            +
            ```
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
            Example class, that inherits from **ApplicationElasticsearchRecord**
         
     | 
| 
       108 
128 
     | 
    
         | 
| 
      
 129 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 130 
     | 
    
         
            +
            # app/models/search.rb
         
     | 
| 
      
 131 
     | 
    
         
            +
               
         
     | 
| 
      
 132 
     | 
    
         
            +
            class Search < ApplicationElasticsearchRecord
         
     | 
| 
      
 133 
     | 
    
         
            +
              
         
     | 
| 
      
 134 
     | 
    
         
            +
            end
         
     | 
| 
       109 
135 
     | 
    
         
             
            ```
         
     | 
| 
       110 
136 
     | 
    
         | 
| 
       111 
137 
     | 
    
         
             
            ### d) have FUN with your model:
         
     | 
| 
         @@ -239,11 +265,80 @@ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/g 
     | 
|
| 
       239 
265 
     | 
    
         | 
| 
       240 
266 
     | 
    
         
             
            -----
         
     | 
| 
       241 
267 
     | 
    
         | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
       243 
     | 
    
         
            -
             
     | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
      
 268 
     | 
    
         
            +
            ## Useful model class attributes
         
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
            ### index_base_name
         
     | 
| 
      
 271 
     | 
    
         
            +
            Rails resolves a pluralized underscore table_name from the class name by default - which will not work for some models.
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
            To support a generic +table_name_prefix+ & +table_name_suffix+ from the _database.yml_, 
         
     | 
| 
      
 274 
     | 
    
         
            +
            the 'index_base_name' provides a possibility to chain prefix, **base** and suffix.
         
     | 
| 
      
 275 
     | 
    
         
            +
             
     | 
| 
      
 276 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 277 
     | 
    
         
            +
            class UnusalStat < ApplicationElasticsearchRecord
         
     | 
| 
      
 278 
     | 
    
         
            +
              self.index_base_name = 'unusal-stats'
         
     | 
| 
      
 279 
     | 
    
         
            +
            end
         
     | 
| 
      
 280 
     | 
    
         
            +
             
     | 
| 
      
 281 
     | 
    
         
            +
            UnusalStat.where(year: 2023).to_query
         
     | 
| 
      
 282 
     | 
    
         
            +
            # => {:index=>"app-unusal-stats-development", :body ...
         
     | 
| 
      
 283 
     | 
    
         
            +
            ```
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
            ### delegate_id_attribute
         
     | 
| 
      
 286 
     | 
    
         
            +
            Rails resolves the primary_key's value by accessing the **#id** method.
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
            Since Elasticsearch also supports an additional, independent **id** attribute,
         
     | 
| 
      
 289 
     | 
    
         
            +
            it would only be able to access this through `_read_attribute(:id)`.
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
            To also have the ability of accessing this attribute through the default, this flag can be enabled.
         
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 294 
     | 
    
         
            +
            class SearchUser < ApplicationElasticsearchRecord
         
     | 
| 
      
 295 
     | 
    
         
            +
              # attributes: id, name
         
     | 
| 
      
 296 
     | 
    
         
            +
            end
         
     | 
| 
      
 297 
     | 
    
         
            +
             
     | 
| 
      
 298 
     | 
    
         
            +
            # create new user within the index
         
     | 
| 
      
 299 
     | 
    
         
            +
            user = SearchUser.create(id: 8, name: 'Parker')
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
            # accessing the id, does NOT return the stored id by default - this will be delegated to the primary_key '_id'.
         
     | 
| 
      
 302 
     | 
    
         
            +
            user.id
         
     | 
| 
      
 303 
     | 
    
         
            +
            # => 'b2e34xa2'
         
     | 
| 
      
 304 
     | 
    
         
            +
             
     | 
| 
      
 305 
     | 
    
         
            +
            # -- ENABLE delegation -------------------------------------------------------------------
         
     | 
| 
      
 306 
     | 
    
         
            +
            SearchUser.delegate_id_attribute = true
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
            # create new user within the index
         
     | 
| 
      
 309 
     | 
    
         
            +
            user = SearchUser.create(id: 9, name: 'Pam')
         
     | 
| 
      
 310 
     | 
    
         
            +
             
     | 
| 
      
 311 
     | 
    
         
            +
            # accessing the id accesses the stored attribute now
         
     | 
| 
      
 312 
     | 
    
         
            +
            user.id
         
     | 
| 
      
 313 
     | 
    
         
            +
            # => 9
         
     | 
| 
      
 314 
     | 
    
         
            +
             
     | 
| 
      
 315 
     | 
    
         
            +
            # accessing the ES index id
         
     | 
| 
      
 316 
     | 
    
         
            +
            user._id
         
     | 
| 
      
 317 
     | 
    
         
            +
            # => 'xtf31bh8x'
         
     | 
| 
      
 318 
     | 
    
         
            +
            ```
         
     | 
| 
      
 319 
     | 
    
         
            +
             
     | 
| 
      
 320 
     | 
    
         
            +
            ## delegate_query_nil_limit
         
     | 
| 
      
 321 
     | 
    
         
            +
            Elasticsearch's default value for queries without a **size** is forced to **10**.
         
     | 
| 
      
 322 
     | 
    
         
            +
            To provide a similar behaviour as the (my)SQL interface,
         
     | 
| 
      
 323 
     | 
    
         
            +
            this can be automatically set to the `max_result_window` value by calling `.limit(nil)` on the models' relation.
         
     | 
| 
       245 
324 
     | 
    
         | 
| 
       246 
     | 
    
         
            -
             
     | 
| 
      
 325 
     | 
    
         
            +
             
     | 
| 
      
 326 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 327 
     | 
    
         
            +
            SearchUser.where(name: 'Peter').limit(nil)
         
     | 
| 
      
 328 
     | 
    
         
            +
            # returns a maximum of 10 items ...
         
     | 
| 
      
 329 
     | 
    
         
            +
            # => [...]
         
     | 
| 
      
 330 
     | 
    
         
            +
             
     | 
| 
      
 331 
     | 
    
         
            +
            # -- ENABLE delegation -------------------------------------------------------------------
         
     | 
| 
      
 332 
     | 
    
         
            +
            SearchUser.delegate_query_nil_limit = true
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
            SearchUser.where(name: 'Peter').limit(nil)
         
     | 
| 
      
 335 
     | 
    
         
            +
            # returns up to 10_000 items ...
         
     | 
| 
      
 336 
     | 
    
         
            +
            # => [...]
         
     | 
| 
      
 337 
     | 
    
         
            +
             
     | 
| 
      
 338 
     | 
    
         
            +
            # hint: if you want more than 10_000 use the +#pit_results+ method!
         
     | 
| 
      
 339 
     | 
    
         
            +
            ```
         
     | 
| 
      
 340 
     | 
    
         
            +
             
     | 
| 
      
 341 
     | 
    
         
            +
            ## Useful model class methods
         
     | 
| 
       247 
342 
     | 
    
         
             
            - auto_increment?
         
     | 
| 
       248 
343 
     | 
    
         
             
            - max_result_window
         
     | 
| 
       249 
344 
     | 
    
         
             
            - source_column_names
         
     | 
| 
         @@ -251,26 +346,28 @@ _see simple documentation about these methods @ [rubydoc](https://rubydoc.info/g 
     | 
|
| 
       251 
346 
     | 
    
         
             
            - find_by_query
         
     | 
| 
       252 
347 
     | 
    
         
             
            - msearch
         
     | 
| 
       253 
348 
     | 
    
         | 
| 
       254 
     | 
    
         
            -
             
     | 
| 
       255 
     | 
    
         
            -
             
     | 
| 
      
 349 
     | 
    
         
            +
            ## Useful model API methods
         
     | 
| 
      
 350 
     | 
    
         
            +
            Quick access to model-related methods for easier access without creating a overcomplicated method call on the models connection...
         
     | 
| 
       256 
351 
     | 
    
         | 
| 
       257 
352 
     | 
    
         
             
            Access these methods through the model class method `.api`.
         
     | 
| 
       258 
353 
     | 
    
         
             
            ```ruby
         
     | 
| 
       259 
     | 
    
         
            -
             
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
      
 354 
     | 
    
         
            +
            # returns mapping of model class
         
     | 
| 
      
 355 
     | 
    
         
            +
            klass.api.mappings
         
     | 
| 
       261 
356 
     | 
    
         | 
| 
       262 
     | 
    
         
            -
             
     | 
| 
       263 
     | 
    
         
            -
             
     | 
| 
      
 357 
     | 
    
         
            +
            # e.g. for ElasticUser model
         
     | 
| 
      
 358 
     | 
    
         
            +
            SearchUser.api.mappings
         
     | 
| 
       264 
359 
     | 
    
         | 
| 
       265 
     | 
    
         
            -
             
     | 
| 
       266 
     | 
    
         
            -
             
     | 
| 
      
 360 
     | 
    
         
            +
            # insert new raw data
         
     | 
| 
      
 361 
     | 
    
         
            +
            SearchUser.api.insert([{name: 'Hans', age: 34}, {name: 'Peter', age: 22}])
         
     | 
| 
       267 
362 
     | 
    
         
             
            ```
         
     | 
| 
       268 
363 
     | 
    
         | 
| 
       269 
     | 
    
         
            -
            * open
         
     | 
| 
       270 
     | 
    
         
            -
            * close
         
     | 
| 
       271 
     | 
    
         
            -
            * refresh
         
     | 
| 
       272 
     | 
    
         
            -
            * block
         
     | 
| 
       273 
     | 
    
         
            -
            * unblock
         
     | 
| 
      
 364 
     | 
    
         
            +
            * open!
         
     | 
| 
      
 365 
     | 
    
         
            +
            * close!
         
     | 
| 
      
 366 
     | 
    
         
            +
            * refresh!
         
     | 
| 
      
 367 
     | 
    
         
            +
            * block!
         
     | 
| 
      
 368 
     | 
    
         
            +
            * unblock!
         
     | 
| 
      
 369 
     | 
    
         
            +
            * drop!(confirm: true)
         
     | 
| 
      
 370 
     | 
    
         
            +
            * truncate!(confirm: true)
         
     | 
| 
       274 
371 
     | 
    
         
             
            * mappings
         
     | 
| 
       275 
372 
     | 
    
         
             
            * metas
         
     | 
| 
       276 
373 
     | 
    
         
             
            * settings
         
     | 
| 
         @@ -290,12 +387,14 @@ Fast insert, update, delete raw data 
     | 
|
| 
       290 
387 
     | 
    
         
             
            * delete
         
     | 
| 
       291 
388 
     | 
    
         
             
            * bulk
         
     | 
| 
       292 
389 
     | 
    
         | 
| 
      
 390 
     | 
    
         
            +
            -----
         
     | 
| 
      
 391 
     | 
    
         
            +
             
     | 
| 
       293 
392 
     | 
    
         
             
            ## ActiveRecord ConnectionAdapters table-methods
         
     | 
| 
       294 
393 
     | 
    
         
             
            Access these methods through the model class method `.connection`.
         
     | 
| 
       295 
394 
     | 
    
         | 
| 
       296 
395 
     | 
    
         
             
            ```ruby
         
     | 
| 
       297 
     | 
    
         
            -
             
     | 
| 
       298 
     | 
    
         
            -
             
     | 
| 
      
 396 
     | 
    
         
            +
            # returns mapping of provided table (index)
         
     | 
| 
      
 397 
     | 
    
         
            +
            klass.connection.table_mappings('table-name')
         
     | 
| 
       299 
398 
     | 
    
         
             
            ```
         
     | 
| 
       300 
399 
     | 
    
         | 
| 
       301 
400 
     | 
    
         
             
            - table_mappings
         
     | 
| 
         @@ -316,7 +415,7 @@ Access these methods through the model class method `.connection`. 
     | 
|
| 
       316 
415 
     | 
    
         
             
            ## Active Record Schema migration methods
         
     | 
| 
       317 
416 
     | 
    
         
             
            Access these methods through the model's connection or within any `Migration`.
         
     | 
| 
       318 
417 
     | 
    
         | 
| 
       319 
     | 
    
         
            -
             
     | 
| 
      
 418 
     | 
    
         
            +
            ### cluster actions:
         
     | 
| 
       320 
419 
     | 
    
         
             
            - open_table
         
     | 
| 
       321 
420 
     | 
    
         
             
            - open_tables
         
     | 
| 
       322 
421 
     | 
    
         
             
            - close_table
         
     | 
| 
         @@ -333,7 +432,7 @@ Access these methods through the model's connection or within any `Migration`. 
     | 
|
| 
       333 
432 
     | 
    
         
             
            - change_table
         
     | 
| 
       334 
433 
     | 
    
         
             
            - rename_table
         
     | 
| 
       335 
434 
     | 
    
         | 
| 
       336 
     | 
    
         
            -
             
     | 
| 
      
 435 
     | 
    
         
            +
            ### table actions:
         
     | 
| 
       337 
436 
     | 
    
         
             
            - change_meta
         
     | 
| 
       338 
437 
     | 
    
         
             
            - remove_meta
         
     | 
| 
       339 
438 
     | 
    
         
             
            - add_mapping
         
     | 
| 
         @@ -348,8 +447,10 @@ Access these methods through the model's connection or within any `Migration`. 
     | 
|
| 
       348 
447 
     | 
    
         
             
            - change_alias
         
     | 
| 
       349 
448 
     | 
    
         
             
            - remove_alias
         
     | 
| 
       350 
449 
     | 
    
         | 
| 
      
 450 
     | 
    
         
            +
             
     | 
| 
      
 451 
     | 
    
         
            +
            **Example migration:**
         
     | 
| 
      
 452 
     | 
    
         
            +
             
     | 
| 
       351 
453 
     | 
    
         
             
            ```ruby
         
     | 
| 
       352 
     | 
    
         
            -
            # Example migration
         
     | 
| 
       353 
454 
     | 
    
         
             
            class AddTests < ActiveRecord::Migration[7.0]
         
     | 
| 
       354 
455 
     | 
    
         
             
              def up
         
     | 
| 
       355 
456 
     | 
    
         
             
                create_table "assignments", if_not_exists: true do |t|
         
     | 
| 
         @@ -422,6 +523,47 @@ class AddTests < ActiveRecord::Migration[7.0] 
     | 
|
| 
       422 
523 
     | 
    
         
             
            end
         
     | 
| 
       423 
524 
     | 
    
         
             
            ```
         
     | 
| 
       424 
525 
     | 
    
         | 
| 
      
 526 
     | 
    
         
            +
             
     | 
| 
      
 527 
     | 
    
         
            +
            ## environment-related-table-name:
         
     | 
| 
      
 528 
     | 
    
         
            +
            Using the `_env_table_name`-method will resolve the table (index) name within the current environment,
         
     | 
| 
      
 529 
     | 
    
         
            +
            even if the environments shares the same cluster ...
         
     | 
| 
      
 530 
     | 
    
         
            +
             
     | 
| 
      
 531 
     | 
    
         
            +
            This can be provided through the `database.yml` by using the `table_name_prefix/suffix` configuration keys.
         
     | 
| 
      
 532 
     | 
    
         
            +
            Within the migration the `_env_table_name`-method must be used in combination with the table (index) base name.
         
     | 
| 
      
 533 
     | 
    
         
            +
             
     | 
| 
      
 534 
     | 
    
         
            +
            **Example:**
         
     | 
| 
      
 535 
     | 
    
         
            +
            Production uses a index suffix with '-pro', development uses '-dev' - they share the same cluster, but different indexes.
         
     | 
| 
      
 536 
     | 
    
         
            +
            For the **settings** table:
         
     | 
| 
      
 537 
     | 
    
         
            +
            - settings-pro
         
     | 
| 
      
 538 
     | 
    
         
            +
            - settings-dev
         
     | 
| 
      
 539 
     | 
    
         
            +
             
     | 
| 
      
 540 
     | 
    
         
            +
            A single migration can be created to be used within each environment:
         
     | 
| 
      
 541 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 542 
     | 
    
         
            +
            # Example migration
         
     | 
| 
      
 543 
     | 
    
         
            +
            class AddSettings < ActiveRecord::Migration[7.0]
         
     | 
| 
      
 544 
     | 
    
         
            +
              def up
         
     | 
| 
      
 545 
     | 
    
         
            +
                create_table _env_table_name("settings"), force: true do |t|
         
     | 
| 
      
 546 
     | 
    
         
            +
                  t.mapping :created_at, :date
         
     | 
| 
      
 547 
     | 
    
         
            +
                  t.mapping :key, :integer do |m|
         
     | 
| 
      
 548 
     | 
    
         
            +
                    m.primary_key = true
         
     | 
| 
      
 549 
     | 
    
         
            +
                    m.auto_increment = 10
         
     | 
| 
      
 550 
     | 
    
         
            +
                  end
         
     | 
| 
      
 551 
     | 
    
         
            +
                  t.mapping :status, :keyword
         
     | 
| 
      
 552 
     | 
    
         
            +
                  t.mapping :updated_at, :date
         
     | 
| 
      
 553 
     | 
    
         
            +
                  t.mapping :value, :text
         
     | 
| 
      
 554 
     | 
    
         
            +
             
     | 
| 
      
 555 
     | 
    
         
            +
                  t.setting "index.number_of_replicas", "0"
         
     | 
| 
      
 556 
     | 
    
         
            +
                  t.setting "index.number_of_shards", "1"
         
     | 
| 
      
 557 
     | 
    
         
            +
                  t.setting "index.routing.allocation.include._tier_preference", "data_content"
         
     | 
| 
      
 558 
     | 
    
         
            +
                end
         
     | 
| 
      
 559 
     | 
    
         
            +
              end 
         
     | 
| 
      
 560 
     | 
    
         
            +
              
         
     | 
| 
      
 561 
     | 
    
         
            +
              def down
         
     | 
| 
      
 562 
     | 
    
         
            +
                drop_table _env_table_name("settings")
         
     | 
| 
      
 563 
     | 
    
         
            +
              end
         
     | 
| 
      
 564 
     | 
    
         
            +
            end 
         
     | 
| 
      
 565 
     | 
    
         
            +
            ```
         
     | 
| 
      
 566 
     | 
    
         
            +
             
     | 
| 
       425 
567 
     | 
    
         
             
            ## Docs
         
     | 
| 
       426 
568 
     | 
    
         | 
| 
       427 
569 
     | 
    
         
             
            [CHANGELOG](docs/CHANGELOG.md)
         
     | 
    
        data/docs/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,5 +1,17 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # ElasticsearchRecord - CHANGELOG
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            ## [1.5.0] - 2023-07-10
         
     | 
| 
      
 4 
     | 
    
         
            +
            * [add] additional `ElasticsearchRecord::ModelApi` methods **drop!** & **truncate!**, which have to be called with a `confirm:true` parameter
         
     | 
| 
      
 5 
     | 
    
         
            +
            * [add] `.ElasticsearchRecord::Base.delegate_query_nil_limit` to automatically delegate a relations `limit(nil)`-call to the **max_result_window** _(set to 10.000 as default)_
         
     | 
| 
      
 6 
     | 
    
         
            +
            * [add] `ActiveRecord::ConnectionAdapters::Elasticsearch::SchemaStatements#access_shard_doc?` which checks, if the **PIT**-shard_doc order is available
         
     | 
| 
      
 7 
     | 
    
         
            +
            * [add] support for **_shard_doc** as a default order for `ElasticsearchRecord::Relation#pit_results`
         
     | 
| 
      
 8 
     | 
    
         
            +
            * [ref] `.ElasticsearchRecord::Base.relay_id_attribute` to a more coherent name: `delegate_id_attribute` 
         
     | 
| 
      
 9 
     | 
    
         
            +
            * [ref] `ElasticsearchRecord::Relation#ordered_relation` to optimize already ordered relations
         
     | 
| 
      
 10 
     | 
    
         
            +
            * [ref] gemspecs to support different versions of Elasticsearch
         
     | 
| 
      
 11 
     | 
    
         
            +
            * [ref] improved README
         
     | 
| 
      
 12 
     | 
    
         
            +
            * [fix] `ElasticsearchRecord::Relation#pit_results` infinite loop _(caused by missing order)_
         
     | 
| 
      
 13 
     | 
    
         
            +
            * [fix] `ElasticsearchRecord::Relation#pit_results` results generation without 'uniq' check of the array
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
       3 
15 
     | 
    
         
             
            ## [1.4.0] - 2023-01-27
         
     | 
| 
       4 
16 
     | 
    
         
             
            * [add] `ElasticsearchRecord::ModelApi` for fast & easy access the elasticsearch index - callable through `.api` (e.g. ElasticUser.api.mappings)
         
     | 
| 
       5 
17 
     | 
    
         
             
            * [ref] `ElasticsearchRecord::Instrumentation::LogSubscriber` to truncate the query-string (default: 1000)
         
     | 
| 
         @@ -32,8 +32,8 @@ DESC 
     | 
|
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
              spec.require_paths = ["lib"]
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
              spec.add_dependency 'activerecord', '~> 7.0 
     | 
| 
       36 
     | 
    
         
            -
              spec.add_dependency 'elasticsearch', ' 
     | 
| 
      
 35 
     | 
    
         
            +
              spec.add_dependency 'activerecord', '~> 7.0'
         
     | 
| 
      
 36 
     | 
    
         
            +
              spec.add_dependency 'elasticsearch', '>= 7.17'
         
     | 
| 
       37 
37 
     | 
    
         | 
| 
       38 
38 
     | 
    
         
             
              #spec.add_development_dependency 'coveralls_reborn', '~> 0.25'
         
     | 
| 
       39 
39 
     | 
    
         
             
              spec.add_development_dependency 'rspec', '~> 3.0'
         
     | 
| 
         @@ -376,6 +376,14 @@ module ActiveRecord 
     | 
|
| 
       376 
376 
     | 
    
         
             
                        @access_id_fielddata
         
     | 
| 
       377 
377 
     | 
    
         
             
                      end
         
     | 
| 
       378 
378 
     | 
    
         | 
| 
      
 379 
     | 
    
         
            +
                      # returns true if +_shard_doc+ field can be accessed through PIT-search.
         
     | 
| 
      
 380 
     | 
    
         
            +
                      # @return [Boolean]
         
     | 
| 
      
 381 
     | 
    
         
            +
                      def access_shard_doc?
         
     | 
| 
      
 382 
     | 
    
         
            +
                        @access_shard_doc = cluster_info[:version] >= "7.12" if @access_shard_doc.nil?
         
     | 
| 
      
 383 
     | 
    
         
            +
             
     | 
| 
      
 384 
     | 
    
         
            +
                        @access_shard_doc
         
     | 
| 
      
 385 
     | 
    
         
            +
                      end
         
     | 
| 
      
 386 
     | 
    
         
            +
             
     | 
| 
       379 
387 
     | 
    
         
             
                      # Returns basic information about the cluster.
         
     | 
| 
       380 
388 
     | 
    
         
             
                      # @return [Hash{Symbol->Unknown}]
         
     | 
| 
       381 
389 
     | 
    
         
             
                      def cluster_info
         
     | 
| 
         @@ -5,20 +5,25 @@ module ElasticsearchRecord 
     | 
|
| 
       5 
5 
     | 
    
         
             
                included do
         
     | 
| 
       6 
6 
     | 
    
         
             
                  # Rails resolves the primary_key's value by accessing the +#id+ method.
         
     | 
| 
       7 
7 
     | 
    
         
             
                  # Since Elasticsearch also supports an additional, independent +id+ attribute, it would only be able to access
         
     | 
| 
       8 
     | 
    
         
            -
                  # this through + 
     | 
| 
      
 8 
     | 
    
         
            +
                  # this through +_read_attribute(:id)+.
         
     | 
| 
       9 
9 
     | 
    
         
             
                  # To also have the ability of accessing this attribute through the default, this flag can be enabled.
         
     | 
| 
       10 
10 
     | 
    
         
             
                  # @attribute! Boolean
         
     | 
| 
       11 
     | 
    
         
            -
                  class_attribute : 
     | 
| 
      
 11 
     | 
    
         
            +
                  class_attribute :delegate_id_attribute, instance_writer: false, default: false
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  # Elasticsearch's default value for queries without a +size+ is forced to +10+.
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # To provide a similar behaviour as SQL, this can be automatically set to the +max_result_window+ value.
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # @attribute! Boolean
         
     | 
| 
      
 16 
     | 
    
         
            +
                  class_attribute :delegate_query_nil_limit, instance_writer: false, default: false
         
     | 
| 
       12 
17 
     | 
    
         
             
                end
         
     | 
| 
       13 
18 
     | 
    
         | 
| 
       14 
19 
     | 
    
         
             
                # overwrite to provide a Elasticsearch version of returning a 'primary_key' attribute.
         
     | 
| 
       15 
20 
     | 
    
         
             
                # Elasticsearch uses the static +_id+ column as primary_key, but also supports an additional +id+ column.
         
     | 
| 
       16 
21 
     | 
    
         
             
                # To provide functionality of returning the +id+ attribute, this method must also support it
         
     | 
| 
       17 
     | 
    
         
            -
                # with enabled + 
     | 
| 
      
 22 
     | 
    
         
            +
                # with enabled +delegate_id_attribute+.
         
     | 
| 
       18 
23 
     | 
    
         
             
                # @return [Object]
         
     | 
| 
       19 
24 
     | 
    
         
             
                def id
         
     | 
| 
       20 
25 
     | 
    
         
             
                  # check, if the model has a +id+ attribute
         
     | 
| 
       21 
     | 
    
         
            -
                  return _read_attribute('id') if  
     | 
| 
      
 26 
     | 
    
         
            +
                  return _read_attribute('id') if delegate_id_attribute? && has_attribute?('id')
         
     | 
| 
       22 
27 
     | 
    
         | 
| 
       23 
28 
     | 
    
         
             
                  super
         
     | 
| 
       24 
29 
     | 
    
         
             
                end
         
     | 
| 
         @@ -26,11 +31,11 @@ module ElasticsearchRecord 
     | 
|
| 
       26 
31 
     | 
    
         
             
                # overwrite to provide a Elasticsearch version of setting a 'primary_key' attribute.
         
     | 
| 
       27 
32 
     | 
    
         
             
                # Elasticsearch uses the static +_id+ column as primary_key, but also supports an additional +id+ column.
         
     | 
| 
       28 
33 
     | 
    
         
             
                # To provide functionality of setting the +id+ attribute, this method must also support it
         
     | 
| 
       29 
     | 
    
         
            -
                # with enabled + 
     | 
| 
      
 34 
     | 
    
         
            +
                # with enabled +delegate_id_attribute+.
         
     | 
| 
       30 
35 
     | 
    
         
             
                # @param [Object] value
         
     | 
| 
       31 
36 
     | 
    
         
             
                def id=(value)
         
     | 
| 
       32 
37 
     | 
    
         
             
                  # check, if the model has a +id+ attribute
         
     | 
| 
       33 
     | 
    
         
            -
                  return _write_attribute('id', value) if  
     | 
| 
      
 38 
     | 
    
         
            +
                  return _write_attribute('id', value) if delegate_id_attribute? && has_attribute?('id')
         
     | 
| 
       34 
39 
     | 
    
         | 
| 
       35 
40 
     | 
    
         
             
                  # auxiliary update the +_id+ virtual column if we have a different primary_key
         
     | 
| 
       36 
41 
     | 
    
         
             
                  _write_attribute('_id', value) if @primary_key != '_id'
         
     | 
| 
         @@ -41,13 +46,13 @@ module ElasticsearchRecord 
     | 
|
| 
       41 
46 
     | 
    
         
             
                # overwrite to provide a Elasticsearch version of returning a 'primary_key' was attribute.
         
     | 
| 
       42 
47 
     | 
    
         
             
                # Elasticsearch uses the static +_id+ column as primary_key, but also supports an additional +id+ column.
         
     | 
| 
       43 
48 
     | 
    
         
             
                # To provide functionality of returning the +id_Was+ attribute, this method must also support it
         
     | 
| 
       44 
     | 
    
         
            -
                # with enabled + 
     | 
| 
      
 49 
     | 
    
         
            +
                # with enabled +delegate_id_attribute+.
         
     | 
| 
       45 
50 
     | 
    
         
             
                def id_was
         
     | 
| 
       46 
     | 
    
         
            -
                   
     | 
| 
      
 51 
     | 
    
         
            +
                  delegate_id_attribute? && has_attribute?('id') ? attribute_was('id') : super
         
     | 
| 
       47 
52 
     | 
    
         
             
                end
         
     | 
| 
       48 
53 
     | 
    
         | 
| 
       49 
54 
     | 
    
         
             
                # overwrite the write_attribute method to always write to the 'id'-attribute, if present.
         
     | 
| 
       50 
     | 
    
         
            -
                # This methods does not check for + 
     | 
| 
      
 55 
     | 
    
         
            +
                # This methods does not check for +delegate_id_attribute+ flag!
         
     | 
| 
       51 
56 
     | 
    
         
             
                # see @ ActiveRecord::AttributeMethods::Write#write_attribute
         
     | 
| 
       52 
57 
     | 
    
         
             
                def write_attribute(attr_name, value)
         
     | 
| 
       53 
58 
     | 
    
         
             
                  return _write_attribute('id', value) if attr_name.to_s == 'id' && has_attribute?('id')
         
     | 
| 
         @@ -56,7 +61,7 @@ module ElasticsearchRecord 
     | 
|
| 
       56 
61 
     | 
    
         
             
                end
         
     | 
| 
       57 
62 
     | 
    
         | 
| 
       58 
63 
     | 
    
         
             
                # overwrite read_attribute method to read from the 'id'-attribute, if present.
         
     | 
| 
       59 
     | 
    
         
            -
                # This methods does not check for + 
     | 
| 
      
 64 
     | 
    
         
            +
                # This methods does not check for +delegate_id_attribute+ flag!
         
     | 
| 
       60 
65 
     | 
    
         
             
                # see @ ActiveRecord::AttributeMethods::Read#read_attribute
         
     | 
| 
       61 
66 
     | 
    
         
             
                def read_attribute(attr_name, &block)
         
     | 
| 
       62 
67 
     | 
    
         
             
                  return _read_attribute('id', &block) if attr_name.to_s == 'id' && has_attribute?('id')
         
     | 
| 
         @@ -8,18 +8,47 @@ module ElasticsearchRecord 
     | 
|
| 
       8 
8 
     | 
    
         
             
                  @klass = klass
         
     | 
| 
       9 
9 
     | 
    
         
             
                end
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                # undelegated schema methods: clone rename create 
     | 
| 
      
 11 
     | 
    
         
            +
                # undelegated schema methods: clone rename create
         
     | 
| 
       12 
12 
     | 
    
         
             
                # those should not be quick-accessible, since they might end in heavily broken index
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                # delegated dangerous methods (created with exclamation mark)
         
     | 
| 
       15 
     | 
    
         
            -
                # not able to provide individual arguments - always the defaults will be used
         
     | 
| 
      
 15 
     | 
    
         
            +
                # not able to provide individual arguments - always the defaults will be used!
         
     | 
| 
      
 16 
     | 
    
         
            +
                #
         
     | 
| 
      
 17 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 18 
     | 
    
         
            +
                #   open!
         
     | 
| 
      
 19 
     | 
    
         
            +
                #   close!
         
     | 
| 
      
 20 
     | 
    
         
            +
                #   refresh!
         
     | 
| 
      
 21 
     | 
    
         
            +
                #   block!
         
     | 
| 
      
 22 
     | 
    
         
            +
                #   unblock!
         
     | 
| 
       16 
23 
     | 
    
         
             
                %w(open close refresh block unblock).each do |method|
         
     | 
| 
       17 
24 
     | 
    
         
             
                  define_method("#{method}!") do
         
     | 
| 
       18 
25 
     | 
    
         
             
                    _connection.send("#{method}_table", _index_name)
         
     | 
| 
       19 
26 
     | 
    
         
             
                  end
         
     | 
| 
       20 
27 
     | 
    
         
             
                end
         
     | 
| 
       21 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
                # delegated dangerous methods with confirm parameter (created with exclamation mark)
         
     | 
| 
      
 30 
     | 
    
         
            +
                # a exception will be raised, if +confirm:true+ is missing.
         
     | 
| 
      
 31 
     | 
    
         
            +
                #
         
     | 
| 
      
 32 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 33 
     | 
    
         
            +
                #   drop!(confirm: true)
         
     | 
| 
      
 34 
     | 
    
         
            +
                #   truncate!(confirm: true)
         
     | 
| 
      
 35 
     | 
    
         
            +
                %w(drop truncate).each do |method|
         
     | 
| 
      
 36 
     | 
    
         
            +
                  define_method("#{method}!") do |confirmed: false|
         
     | 
| 
      
 37 
     | 
    
         
            +
                    raise "#{method} of table '#{_index_name}' aborted!\nexecution not confirmed!\ncall with: #{klass}.api.#{method}!(confirmed: true)" unless confirmed
         
     | 
| 
      
 38 
     | 
    
         
            +
                    _connection.send("#{method}_table", _index_name)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
                end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
       22 
42 
     | 
    
         
             
                # delegated table methods
         
     | 
| 
      
 43 
     | 
    
         
            +
                #
         
     | 
| 
      
 44 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 45 
     | 
    
         
            +
                #   mappings
         
     | 
| 
      
 46 
     | 
    
         
            +
                #   metas
         
     | 
| 
      
 47 
     | 
    
         
            +
                #   settings
         
     | 
| 
      
 48 
     | 
    
         
            +
                #   aliases
         
     | 
| 
      
 49 
     | 
    
         
            +
                #   state
         
     | 
| 
      
 50 
     | 
    
         
            +
                #   schema
         
     | 
| 
      
 51 
     | 
    
         
            +
                #   exists?
         
     | 
| 
       23 
52 
     | 
    
         
             
                %w(mappings metas settings aliases state schema exists?).each do |method|
         
     | 
| 
       24 
53 
     | 
    
         
             
                  define_method(method) do |*args|
         
     | 
| 
       25 
54 
     | 
    
         
             
                    _connection.send("table_#{method}", _index_name, *args)
         
     | 
| 
         @@ -27,6 +56,12 @@ module ElasticsearchRecord 
     | 
|
| 
       27 
56 
     | 
    
         
             
                end
         
     | 
| 
       28 
57 
     | 
    
         | 
| 
       29 
58 
     | 
    
         
             
                # delegated plain methods
         
     | 
| 
      
 59 
     | 
    
         
            +
                #
         
     | 
| 
      
 60 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 61 
     | 
    
         
            +
                #   alias_exists?
         
     | 
| 
      
 62 
     | 
    
         
            +
                #   setting_exists?
         
     | 
| 
      
 63 
     | 
    
         
            +
                #   mapping_exists?
         
     | 
| 
      
 64 
     | 
    
         
            +
                #   meta_exists?
         
     | 
| 
       30 
65 
     | 
    
         
             
                %w(alias_exists? setting_exists? mapping_exists? meta_exists?).each do |method|
         
     | 
| 
       31 
66 
     | 
    
         
             
                  define_method(method) do |*args|
         
     | 
| 
       32 
67 
     | 
    
         
             
                    _connection.send(method, _index_name, *args)
         
     | 
| 
         @@ -89,7 +124,7 @@ module ElasticsearchRecord 
     | 
|
| 
       89 
124 
     | 
    
         
             
                  if data[0].is_a?(Hash)
         
     | 
| 
       90 
125 
     | 
    
         
             
                    bulk(data, :delete, **options)
         
     | 
| 
       91 
126 
     | 
    
         
             
                  else
         
     | 
| 
       92 
     | 
    
         
            -
                    bulk(data.map{|id| {id: id}}, :delete, **options)
         
     | 
| 
      
 127 
     | 
    
         
            +
                    bulk(data.map { |id| { id: id } }, :delete, **options)
         
     | 
| 
       93 
128 
     | 
    
         
             
                  end
         
     | 
| 
       94 
129 
     | 
    
         
             
                end
         
     | 
| 
       95 
130 
     | 
    
         | 
| 
         @@ -102,7 +137,7 @@ module ElasticsearchRecord 
     | 
|
| 
       102 
137 
     | 
    
         | 
| 
       103 
138 
     | 
    
         
             
                  _connection.api(:core, :bulk, {
         
     | 
| 
       104 
139 
     | 
    
         
             
                    index:   _index_name,
         
     | 
| 
       105 
     | 
    
         
            -
                    body:    data.map{|item| {operation => {_id: item[:id], data: item.except(:id)}}},
         
     | 
| 
      
 140 
     | 
    
         
            +
                    body:    data.map { |item| { operation => { _id: item[:id], data: item.except(:id) } } },
         
     | 
| 
       106 
141 
     | 
    
         
             
                    refresh: refresh
         
     | 
| 
       107 
142 
     | 
    
         
             
                  }, "BULK #{operation.to_s.upcase}", **options)
         
     | 
| 
       108 
143 
     | 
    
         
             
                end
         
     | 
| 
         @@ -99,21 +99,29 @@ module ElasticsearchRecord 
     | 
|
| 
       99 
99 
     | 
    
         
             
                  # overwrite original methods to provide a elasticsearch version:
         
     | 
| 
       100 
100 
     | 
    
         
             
                  # checks against the +#access_id_fielddata?+ to ensure the Elasticsearch Cluster allows access on the +_id+ field.
         
     | 
| 
       101 
101 
     | 
    
         
             
                  def ordered_relation
         
     | 
| 
       102 
     | 
    
         
            -
                    #  
     | 
| 
      
 102 
     | 
    
         
            +
                    # order values already exist
         
     | 
| 
      
 103 
     | 
    
         
            +
                    return self unless order_values.empty?
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                    # resolve valid primary_key
         
     | 
| 
      
 106 
     | 
    
         
            +
                    # - either it is NOT the '_id' column
         
     | 
| 
      
 107 
     | 
    
         
            +
                    # OR
         
     | 
| 
      
 108 
     | 
    
         
            +
                    # - it is the '_id'-column, but +access_id_fielddata?+ is also enabled!
         
     | 
| 
       103 
109 
     | 
    
         
             
                    valid_primary_key = if primary_key != '_id' || klass.connection.access_id_fielddata?
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
             
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
      
 110 
     | 
    
         
            +
                                          primary_key
         
     | 
| 
      
 111 
     | 
    
         
            +
                                        else
         
     | 
| 
      
 112 
     | 
    
         
            +
                                          nil
         
     | 
| 
      
 113 
     | 
    
         
            +
                                        end
         
     | 
| 
       108 
114 
     | 
    
         | 
| 
       109 
115 
     | 
    
         
             
                    # slightly changed original methods content
         
     | 
| 
       110 
     | 
    
         
            -
                    if  
     | 
| 
      
 116 
     | 
    
         
            +
                    if implicit_order_column || valid_primary_key
         
     | 
| 
      
 117 
     | 
    
         
            +
                      # order by +implicit_order_column+ AND +primary_key+
         
     | 
| 
       111 
118 
     | 
    
         
             
                      if implicit_order_column && valid_primary_key && implicit_order_column != valid_primary_key
         
     | 
| 
       112 
119 
     | 
    
         
             
                        order(table[implicit_order_column].asc, table[valid_primary_key].asc)
         
     | 
| 
       113 
120 
     | 
    
         
             
                      else
         
     | 
| 
       114 
121 
     | 
    
         
             
                        order(table[implicit_order_column || valid_primary_key].asc)
         
     | 
| 
       115 
122 
     | 
    
         
             
                      end
         
     | 
| 
       116 
123 
     | 
    
         
             
                    else
         
     | 
| 
      
 124 
     | 
    
         
            +
                      # order is not possible due restricted settings
         
     | 
| 
       117 
125 
     | 
    
         
             
                      self
         
     | 
| 
       118 
126 
     | 
    
         
             
                    end
         
     | 
| 
       119 
127 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -91,15 +91,20 @@ module ElasticsearchRecord 
     | 
|
| 
       91 
91 
     | 
    
         
             
                  # @param [String] keep_alive - how long to keep alive (for each single request) - default: '1m'
         
     | 
| 
       92 
92 
     | 
    
         
             
                  # @param [Integer] batch_size - how many results per query (default: 1000 - this means at least 10 queries before reaching the +max_result_window+)
         
     | 
| 
       93 
93 
     | 
    
         
             
                  def pit_results(keep_alive: '1m', batch_size: 1000)
         
     | 
| 
       94 
     | 
    
         
            -
                    raise 
     | 
| 
      
 94 
     | 
    
         
            +
                    raise(ArgumentError, "Batch size cannot be above the 'max_result_window' (#{klass.max_result_window}) !") if batch_size > klass.max_result_window
         
     | 
| 
       95 
95 
     | 
    
         | 
| 
       96 
     | 
    
         
            -
                    # check if  
     | 
| 
      
 96 
     | 
    
         
            +
                    # check if limit or offset values where provided
         
     | 
| 
       97 
97 
     | 
    
         
             
                    results_limit  = limit_value ? limit_value : Float::INFINITY
         
     | 
| 
       98 
98 
     | 
    
         
             
                    results_offset = offset_value ? offset_value : 0
         
     | 
| 
       99 
99 
     | 
    
         | 
| 
       100 
100 
     | 
    
         
             
                    # search_after requires a order - we resolve a order either from provided value or by default ...
         
     | 
| 
       101 
101 
     | 
    
         
             
                    relation = ordered_relation
         
     | 
| 
       102 
102 
     | 
    
         | 
| 
      
 103 
     | 
    
         
            +
                    # FALLBACK (without any order) for restricted access to the '_id' field.
         
     | 
| 
      
 104 
     | 
    
         
            +
                    # with PIT a order by '_shard_doc' can also be used
         
     | 
| 
      
 105 
     | 
    
         
            +
                    # see @ https://www.elastic.co/guide/en/elasticsearch/reference/current/paginate-search-results.html
         
     | 
| 
      
 106 
     | 
    
         
            +
                    relation.order!(_shard_doc: :asc) if relation.order_values.empty? && klass.connection.access_shard_doc?
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
       103 
108 
     | 
    
         
             
                    # clear limit & offset
         
     | 
| 
       104 
109 
     | 
    
         
             
                    relation.offset!(nil).limit!(nil)
         
     | 
| 
       105 
110 
     | 
    
         | 
| 
         @@ -135,7 +140,7 @@ module ElasticsearchRecord 
     | 
|
| 
       135 
140 
     | 
    
         
             
                          if block_given?
         
     | 
| 
       136 
141 
     | 
    
         
             
                            yield ranged_results
         
     | 
| 
       137 
142 
     | 
    
         
             
                          else
         
     | 
| 
       138 
     | 
    
         
            -
                            results  
     | 
| 
      
 143 
     | 
    
         
            +
                            results += ranged_results
         
     | 
| 
       139 
144 
     | 
    
         
             
                          end
         
     | 
| 
       140 
145 
     | 
    
         | 
| 
       141 
146 
     | 
    
         
             
                          # add to total
         
     | 
| 
         @@ -150,8 +155,8 @@ module ElasticsearchRecord 
     | 
|
| 
       150 
155 
     | 
    
         
             
                        # we ran out of data
         
     | 
| 
       151 
156 
     | 
    
         
             
                        break if current_results_length < batch_size
         
     | 
| 
       152 
157 
     | 
    
         | 
| 
       153 
     | 
    
         
            -
                        # additional security -  
     | 
| 
       154 
     | 
    
         
            -
                         
     | 
| 
      
 158 
     | 
    
         
            +
                        # additional security - prevents infinite loops
         
     | 
| 
      
 159 
     | 
    
         
            +
                        raise(::ActiveRecord::StatementInvalid, "'pit_results' aborted due an infinite loop error (invalid or missing order)") if current_pit_hash[:search_after] == current_response['hits']['hits'][-1]['sort'] && current_pit_hash[:pit][:id] == current_response['pit_id']
         
     | 
| 
       155 
160 
     | 
    
         | 
| 
       156 
161 
     | 
    
         
             
                        # -------- NEXT LOOP changes --------
         
     | 
| 
       157 
162 
     | 
    
         | 
| 
         @@ -43,6 +43,15 @@ module ElasticsearchRecord 
     | 
|
| 
       43 
43 
     | 
    
         
             
                    @values[:aggs] = value
         
     | 
| 
       44 
44 
     | 
    
         
             
                  end
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
      
 46 
     | 
    
         
            +
                  # overwrite the limit_value setter, to provide a special behaviour of auto-setting the +max_result_window+.
         
     | 
| 
      
 47 
     | 
    
         
            +
                  def limit=(limit)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    if limit == '__max__' || (limit.nil? && delegate_query_nil_limit?)
         
     | 
| 
      
 49 
     | 
    
         
            +
                      super(max_result_window)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    else
         
     | 
| 
      
 51 
     | 
    
         
            +
                      super
         
     | 
| 
      
 52 
     | 
    
         
            +
                    end
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
       46 
55 
     | 
    
         
             
                  private
         
     | 
| 
       47 
56 
     | 
    
         | 
| 
       48 
57 
     | 
    
         
             
                  # alternative method to avoid redefining the const +VALID_UNSCOPING_VALUES+
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: elasticsearch_record
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.5.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Tobias Gonsior
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2023- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2023-07-10 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: activerecord
         
     | 
| 
         @@ -16,28 +16,28 @@ dependencies: 
     | 
|
| 
       16 
16 
     | 
    
         
             
                requirements:
         
     | 
| 
       17 
17 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       18 
18 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       19 
     | 
    
         
            -
                    version: 7.0 
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '7.0'
         
     | 
| 
       20 
20 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       21 
21 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       22 
22 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       23 
23 
     | 
    
         
             
                requirements:
         
     | 
| 
       24 
24 
     | 
    
         
             
                - - "~>"
         
     | 
| 
       25 
25 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       26 
     | 
    
         
            -
                    version: 7.0 
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '7.0'
         
     | 
| 
       27 
27 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       28 
28 
     | 
    
         
             
              name: elasticsearch
         
     | 
| 
       29 
29 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
       30 
30 
     | 
    
         
             
                requirements:
         
     | 
| 
       31 
     | 
    
         
            -
                - - " 
     | 
| 
      
 31 
     | 
    
         
            +
                - - ">="
         
     | 
| 
       32 
32 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       33 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '7.17'
         
     | 
| 
       34 
34 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       35 
35 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       36 
36 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
       37 
37 
     | 
    
         
             
                requirements:
         
     | 
| 
       38 
     | 
    
         
            -
                - - " 
     | 
| 
      
 38 
     | 
    
         
            +
                - - ">="
         
     | 
| 
       39 
39 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       40 
     | 
    
         
            -
                    version: ' 
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '7.17'
         
     | 
| 
       41 
41 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       42 
42 
     | 
    
         
             
              name: rspec
         
     | 
| 
       43 
43 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     |