Install Elasticsearch version 8.x from archive on Linux or MacOS
Install kibana
1
$ brew install elastic/tap/kibana-full
Note: Kibana version must match with Elasticsearch version.
Rails project
1 2 3 4 5
$ gem install rails $ rails new blog --database=postgresql $ cd blog $ rails g scaffold Article title:string body:text $ rake db:create && rake db:migrate
$ rails g model user first_name:string last_name:string $ rails g migration add_user_ref_to_articles user:references $ rails g resource comment article:references body:text
1 2 3 4 5 6 7
classArticle < ApplicationRecord include Searchable # magic goes there
belongs_to :user
has_many :comments, dependent::destroy end
1 2 3
classUser < ApplicationRecord has_many :articles, dependent::destroy end
1 2 3
classComment < ApplicationRecord belongs_to :article end
# } # } # } { # "took" : 0, # "timed_out" : false, # "_shards" : { # "total" : 1, # "successful" : 1, # "skipped" : 0, # "failed" : 0 # }, # "hits" : { # "total" : { # "value" : 2, # "relation" : "eq" # }, # "max_score" : 0.58432883, # "hits" : [ # { # "_index" : "articles", # "_type" : "_doc", # "_id" : "64092", # "_score" : 0.58432883, # "_source" : { # "title" : "Champagne Brain", # "body" : "Expedita repellat accusamus provident hic. Quisquam inventore eligendi error ratione illo. Maxime dolore quidem voluptates qui. Nesciunt.", # "user" : { # "first_name" : "Peggie", # "last_name" : "Lang" # }, # "comments" : [ # { # "body" : "Wanted dead or alive super bowl stars and stripes Van Halen Championship Pro Bass Fishing. Xxxl stars and stripes border wall redwood Garth Brooks commies get out of my country MGD. Lunchables Chuck Norris more bullets national security official sponsor tomahawk cruise missile Dallas Cowboys Hot Pockets bald eagles." # } # ] # } # }, # { # "_index" : "articles", # "_type" : "_doc", # "_id" : "64093", # "_score" : 0.4051479, # "_source" : { # "title" : "Action Tears", # "body" : "Commodi atque voluptatum porro placeat. Commodi eum ea consequatur illo iste autem. Voluptatem quia error dicta quis debitis ut voluptates.", # "user" : { # "first_name" : "Peggie", # "last_name" : "Lang" # }, # "comments" : [ # { # "body" : "Shopping John Wayne propane tanks DiGiorno Medal of Honor foreign policy. Fbi cia nsa hot dogs the media extra pulled pork WMD Star-Spangled Banner congress. Applebee's tomahawk cruise missile fireworks malls God Bless America red white and blue wanted dead or alive. Pro-wrestling dual-wielded machine guns I only speak American democracy ESPN2." # }, # { # "body" : "Liberty 7-Eleven Denny's Grand Slam Breakfast Lynyrd Skynyrd truthers independence 3D Blu-Ray shopping enemies of freedom. Texas mud flaps bald eagles crispy chicken strips Medal of Honor 7-Eleven Checkers NASA. Southwest breakfast burrito Branson Missouri Wal-Mart Chuck Norris 7-Eleven Arnold Schwarzenegger democracy 85oz soda. Pickup trucks DirecTV velcro Chuck Norris microwaved patriotic the government extra beef. Super bowl TGIF credit cards mission accomplished Marlboro reds SUVs 1776 Garth Brooks." # } # ] # } # } # ] # } # } self.__elasticsearch__.search(params).records.to_a end
Keeping index in sync with data
We have a relationships within our articles index and we want to keep index up to date. So every change of comment should update coresponding artile document with that comments and every change in user should update documents with that user. Let’s dive in.
Article.has_many.comments
1 2 3 4 5
classComment < ApplicationRecord belongs_to :article, touch:true# add touch: true # associated object will be touched (the updated_at / updated_on attributes set to current time) when this record is either saved or destroyed. # (...) end
1 2 3 4 5
moduleSearchable included do after_touch() { __elasticsearch__.index_document } # add after_touch callback end # (...)