@@ -38,7 +38,6 @@ or install it from a source code checkout:
38
38
The library provides two different patterns for adding persistence to your Ruby objects:
39
39
40
40
* [ Repository Pattern] ( #the-repository-pattern )
41
- * [ ActiveRecord Pattern] ( #the-activerecord-pattern )
42
41
43
42
### The Repository Pattern
44
43
@@ -445,262 +444,8 @@ and demonstrates a rich set of features:
445
444
446
445
### The ActiveRecord Pattern
447
446
448
- The ` Elasticsearch::Persistence::Model ` module provides an implementation of the
449
- active record [ pattern] ( http://www.martinfowler.com/eaaCatalog/activeRecord.html ) ,
450
- with a familiar interface for using Elasticsearch as a persistence layer in
451
- Ruby on Rails applications.
452
-
453
- All the methods are documented with comprehensive examples in the source code,
454
- available also online at < http://rubydoc.info/gems/elasticsearch-persistence/Elasticsearch/Persistence/Model > .
455
-
456
- #### Installation/Usage
457
-
458
- To use the library in a Rails application, add it to your ` Gemfile ` with a ` require ` statement:
459
-
460
- ``` ruby
461
- gem " elasticsearch-persistence" , require: ' elasticsearch/persistence/model'
462
- ```
463
-
464
- To use the library without Bundler, install it, and require the file:
465
-
466
- ``` bash
467
- gem install elasticsearch-persistence
468
- ```
469
-
470
- ``` ruby
471
- # In your code
472
- require ' elasticsearch/persistence/model'
473
- ```
474
-
475
- #### Model Definition
476
-
477
- The integration is implemented by including the module in a Ruby class.
478
- The model attribute definition support is implemented with the
479
- [ _ Virtus_ ] ( https://github.com/solnic/virtus ) Rubygem, and the
480
- naming, validation, etc. features with the
481
- [ _ ActiveModel_ ] ( https://github.com/rails/rails/tree/master/activemodel ) Rubygem.
482
-
483
- ``` ruby
484
- class Article
485
- include Elasticsearch ::Persistence ::Model
486
-
487
- # Define a plain `title` attribute
488
- #
489
- attribute :title , String
490
-
491
- # Define an `author` attribute, with multiple analyzers for this field
492
- #
493
- attribute :author , String , mapping: { fields: {
494
- author: { type: ' text' },
495
- raw: { type: ' keyword' }
496
- } }
497
-
498
-
499
- # Define a `views` attribute, with default value
500
- #
501
- attribute :views , Integer , default: 0 , mapping: { type: ' integer' }
502
-
503
- # Validate the presence of the `title` attribute
504
- #
505
- validates :title , presence: true
506
-
507
- # Execute code after saving the model.
508
- #
509
- after_save { puts " Successfully saved: #{ self } " }
510
- end
511
- ```
512
-
513
- Attribute validations work like for any other _ ActiveModel_ -compatible implementation:
514
-
515
- ``` ruby
516
- article = Article .new # => #<Article { ... }>
517
-
518
- article.valid?
519
- # => false
520
-
521
- article.errors.to_a
522
- # => ["Title can't be blank"]
523
- ```
524
-
525
- #### Persistence
526
-
527
- We can create a new article in the database...
528
-
529
- ``` ruby
530
- Article .create id: 1 , title: ' Test' , author: ' John'
531
- # PUT http://localhost:9200/articles/article/1 [status:201, request:0.015s, query:n/a]
532
- ```
533
-
534
- ... and find it:
535
-
536
- ``` ruby
537
- article = Article .find(1 )
538
- # => #<Article { ... }>
539
-
540
- article._index
541
- # => "articles"
542
-
543
- article.id
544
- # => "1"
545
-
546
- article.title
547
- # => "Test"
548
- ```
549
-
550
- To update the model, either update the attribute and save the model:
551
-
552
- ``` ruby
553
- article.title = ' Updated'
554
-
555
- article.save
556
- # => {"_index"=>"articles", "_type"=>"article", "_id"=>"1", "_version"=>2, "created"=>false}
557
- ```
558
-
559
- ... or use the ` update_attributes ` method:
560
-
561
- ``` ruby
562
- article.update_attributes title: ' Test' , author: ' Mary'
563
- # => {"_index"=>"articles", "_type"=>"article", "_id"=>"1", "_version"=>3}
564
- ```
565
-
566
- The implementation supports the familiar interface for updating model timestamps:
567
-
568
- ``` ruby
569
- article.touch
570
- # => => { ... "_version"=>4}
571
- ```
572
-
573
- ... and numeric attributes:
574
-
575
- ``` ruby
576
- article.views
577
- # => 0
578
-
579
- article.increment :views
580
- article.views
581
- # => 1
582
- ```
583
-
584
- Any callbacks defined in the model will be triggered during the persistence operations:
585
-
586
- ``` ruby
587
- article.save
588
- # Successfully saved: #<Article {...}>
589
- ```
590
-
591
- The model also supports familiar ` find_in_batches ` and ` find_each ` methods to efficiently
592
- retrieve big collections of model instances, using the Elasticsearch's _ Scan API_ :
593
-
594
- ``` ruby
595
- Article .find_each(_source_include: ' title' ) { |a | puts " ===> #{ a.title.upcase } " }
596
- # GET http://localhost:9200/articles/article/_search?scroll=5m&size=20
597
- # GET http://localhost:9200/_search/scroll?scroll=5m&scroll_id=c2Nhb...
598
- # ===> TEST
599
- # GET http://localhost:9200/_search/scroll?scroll=5m&scroll_id=c2Nhb...
600
- # => "c2Nhb..."
601
- ```
602
-
603
- #### Search
604
-
605
- The model class provides a ` search ` method to retrieve model instances with a regular
606
- search definition, including highlighting, aggregations, etc:
607
-
608
- ``` ruby
609
- results = Article .search query: { match: { title: ' test' } },
610
- aggregations: { authors: { terms: { field: ' author.raw' } } },
611
- highlight: { fields: { title: {} } }
612
-
613
- puts results.first.title
614
- # Test
615
-
616
- puts results.first.hit.highlight[' title' ]
617
- # <em>Test</em>
618
-
619
- puts results.response.aggregations.authors.buckets.each { |b | puts " #{ b[' key' ] } : #{ b[' doc_count' ] } " }
620
- # John : 1
621
- ```
622
-
623
- #### The Elasticsearch Client
624
-
625
- The module will set up a [ client] ( https://github.com/elastic/elasticsearch-ruby/tree/master/elasticsearch ) ,
626
- connected to ` localhost:9200 ` , by default.
627
-
628
- To use a client with different configuration:
629
-
630
- ``` ruby
631
- Elasticsearch ::Persistence .client = Elasticsearch ::Client .new log: true
632
- ```
633
-
634
- To set up a specific client for a specific model:
635
-
636
- ``` ruby
637
- Article .gateway.client = Elasticsearch ::Client .new host: ' api.server.org'
638
- ```
639
-
640
- You might want to do this during you application bootstrap process, e.g. in a Rails initializer.
641
-
642
- Please refer to the
643
- [ ` elasticsearch-transport ` ] ( https://github.com/elasticsearch/elasticsearch-ruby/tree/master/elasticsearch-transport )
644
- library documentation for all the configuration options, and to the
645
- [ ` elasticsearch-api ` ] ( http://rubydoc.info/gems/elasticsearch-api ) library documentation
646
- for information about the Ruby client API.
647
-
648
- #### Accessing the Repository Gateway and the Client
649
-
650
- The integration with Elasticsearch is implemented by embedding the repository object in the model.
651
- You can access it through the ` gateway ` method:
652
-
653
- ``` ruby
654
- Artist .gateway.client.info
655
- # GET http://localhost:9200/ [status:200, request:0.011s, query:n/a]
656
- # => {"status"=>200, "name"=>"Lightspeed", ...}
657
- ```
658
-
659
- #### Rails Compatibility
660
-
661
- The model instances are fully compatible with Rails' conventions and helpers:
662
-
663
- ``` ruby
664
- url_for article
665
- # => "http://localhost:3000/articles/1"
666
-
667
- div_for article
668
- # => '<div class="article" id="article_1"></div>'
669
- ```
670
-
671
- ... as well as form values for dates and times:
672
-
673
- ``` ruby
674
- article = Article .new " title" => " Date" , " published(1i)" =>" 2014" , " published(2i)" =>" 1" , " published(3i)" =>" 1"
675
-
676
- article.published.iso8601
677
- # => "2014-01-01"
678
- ```
679
-
680
- The library provides a Rails ORM generator to facilitate building the application scaffolding:
681
-
682
- ``` bash
683
- rails generate scaffold Person name:String email:String birthday:Date --orm=elasticsearch
684
- ```
685
-
686
- #### Example application
687
-
688
- A fully working Ruby on Rails application can be generated with the following command:
689
-
690
- ``` bash
691
- rails new music --force --skip --skip-bundle --skip-active-record --template https://raw.githubusercontent.com/elastic/elasticsearch-rails/master/elasticsearch-persistence/examples/music/template.rb
692
- ```
693
-
694
- The application demonstrates:
695
-
696
- * How to set up model attributes with custom mappings
697
- * How to define model relationships with Elasticsearch's parent/child
698
- * How to configure models to use a common index, and create the index with proper mappings
699
- * How to use Elasticsearch's completion suggester to drive auto-complete functionality
700
- * How to use Elasticsearch-persisted models in Rails' views and forms
701
- * How to write controller tests
702
-
703
- The source files for the application are available in the [ ` examples/music ` ] ( examples/music ) folder.
447
+ The ActiveRecord pattern has been deprecated as of version 6.0.0 of this gem. Please use the
448
+ [ Repository Pattern] ( #the-repository-pattern ) instead.
704
449
705
450
## License
706
451
0 commit comments