Add Elasticsearch index for classified_listings (#6031) [deploy]
This commit is contained in:
parent
ee5aa1ff1a
commit
0f32eb9db0
3 changed files with 221 additions and 1 deletions
129
app/services/search/classified_listing.rb
Normal file
129
app/services/search/classified_listing.rb
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
module Search
|
||||
class ClassifiedListing
|
||||
INDEX_NAME = "classified_listings_#{Rails.env}".freeze
|
||||
INDEX_ALIAS = "classified_listings_#{Rails.env}_alias".freeze
|
||||
|
||||
class << self
|
||||
def index(classified_listing_id, serialized_data)
|
||||
SearchClient.index(
|
||||
id: classified_listing_id,
|
||||
index: INDEX_ALIAS,
|
||||
body: serialized_data,
|
||||
)
|
||||
end
|
||||
|
||||
def find_document(classified_listing_id)
|
||||
SearchClient.get(id: classified_listing_id, index: INDEX_ALIAS)
|
||||
end
|
||||
|
||||
def create_index(index_name: INDEX_NAME)
|
||||
SearchClient.indices.create(index: index_name, body: settings)
|
||||
end
|
||||
|
||||
def delete_index(index_name: INDEX_NAME)
|
||||
SearchClient.indices.delete(index: index_name)
|
||||
end
|
||||
|
||||
def add_alias(index_name: INDEX_NAME, index_alias: INDEX_ALIAS)
|
||||
SearchClient.indices.put_alias(index: index_name, name: index_alias)
|
||||
end
|
||||
|
||||
def update_mappings(index_alias: INDEX_ALIAS)
|
||||
SearchClient.indices.put_mapping(index: index_alias, body: mappings)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def settings
|
||||
{ settings: { index: index_settings } }
|
||||
end
|
||||
|
||||
def index_settings
|
||||
if Rails.env.production?
|
||||
{
|
||||
number_of_shards: 2,
|
||||
number_of_replicas: 1
|
||||
}
|
||||
else
|
||||
{
|
||||
number_of_shards: 1,
|
||||
number_of_replicas: 0
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def mappings
|
||||
{
|
||||
dynamic: "strict",
|
||||
properties: {
|
||||
id: {
|
||||
type: "keyword"
|
||||
},
|
||||
author: {
|
||||
dynamic: "strict",
|
||||
properties: {
|
||||
username: {
|
||||
type: "keyword"
|
||||
},
|
||||
name: {
|
||||
type: "keyword"
|
||||
},
|
||||
profile_image_90: {
|
||||
type: "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
body_markdown: {
|
||||
type: "text"
|
||||
},
|
||||
bumped_at: {
|
||||
type: "date"
|
||||
},
|
||||
category: {
|
||||
type: "keyword"
|
||||
},
|
||||
contact_via_connect: {
|
||||
type: "boolean"
|
||||
},
|
||||
expires_at: {
|
||||
type: "date"
|
||||
},
|
||||
location: {
|
||||
type: "text",
|
||||
fields: {
|
||||
raw: {
|
||||
type: "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
processed_html: {
|
||||
type: "keyword"
|
||||
},
|
||||
slug: {
|
||||
type: "text",
|
||||
fields: {
|
||||
raw: {
|
||||
type: "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
tags: {
|
||||
type: "keyword"
|
||||
},
|
||||
title: {
|
||||
type: "text",
|
||||
fields: {
|
||||
raw: {
|
||||
type: "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
user_id: {
|
||||
type: "keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
module Search
|
||||
class Cluster
|
||||
SEARCH_CLASSES = [Search::Tag].freeze
|
||||
SEARCH_CLASSES = [
|
||||
Search::Tag,
|
||||
Search::ClassifiedListing,
|
||||
].freeze
|
||||
|
||||
class << self
|
||||
def recreate_indexes
|
||||
|
|
|
|||
88
spec/services/search/classified_listing_spec.rb
Normal file
88
spec/services/search/classified_listing_spec.rb
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe Search::ClassifiedListing, type: :service, elasticsearch: true do
|
||||
describe "::index" do
|
||||
it "indexes a classified_listing to elasticsearch" do
|
||||
classified_listing = FactoryBot.create(:classified_listing)
|
||||
expect { described_class.find_document(classified_listing.id) }.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
|
||||
described_class.index(classified_listing.id, id: classified_listing.id)
|
||||
expect(described_class.find_document(classified_listing.id)).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "::find_document" do
|
||||
it "fetches a document for a given ID from elasticsearch" do
|
||||
classified_listing = FactoryBot.create(:classified_listing)
|
||||
described_class.index(classified_listing.id, id: classified_listing.id)
|
||||
expect { described_class.find_document(classified_listing.id) }.not_to raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe "::create_index" do
|
||||
it "creates an elasticsearch index with INDEX_NAME" do
|
||||
described_class.delete_index
|
||||
expect(SearchClient.indices.exists(index: described_class::INDEX_NAME)).to eq(false)
|
||||
described_class.create_index
|
||||
expect(SearchClient.indices.exists(index: described_class::INDEX_NAME)).to eq(true)
|
||||
end
|
||||
|
||||
it "creates an elasticsearch index with name argument" do
|
||||
other_name = "random"
|
||||
expect(SearchClient.indices.exists(index: other_name)).to eq(false)
|
||||
described_class.create_index(index_name: other_name)
|
||||
expect(SearchClient.indices.exists(index: other_name)).to eq(true)
|
||||
|
||||
# Have to cleanup index since it wont automatically be handled by our cluster class bc of the unexpected name
|
||||
described_class.delete_index(index_name: other_name)
|
||||
end
|
||||
end
|
||||
|
||||
describe "::delete_index" do
|
||||
it "deletes an elasticsearch index with INDEX_NAME" do
|
||||
expect(SearchClient.indices.exists(index: described_class::INDEX_NAME)).to eq(true)
|
||||
described_class.delete_index
|
||||
expect(SearchClient.indices.exists(index: described_class::INDEX_NAME)).to eq(false)
|
||||
end
|
||||
|
||||
it "deletes an elasticsearch index with name argument" do
|
||||
other_name = "random"
|
||||
described_class.create_index(index_name: other_name)
|
||||
expect(SearchClient.indices.exists(index: other_name)).to eq(true)
|
||||
|
||||
described_class.delete_index(index_name: other_name)
|
||||
expect(SearchClient.indices.exists(index: other_name)).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe "::add_alias" do
|
||||
it "adds alias INDEX_ALIAS to elasticsearch index with INDEX_NAME" do
|
||||
SearchClient.indices.delete_alias(index: described_class::INDEX_NAME, name: described_class::INDEX_ALIAS)
|
||||
expect(SearchClient.indices.exists(index: described_class::INDEX_ALIAS)).to eq(false)
|
||||
described_class.add_alias
|
||||
expect(SearchClient.indices.exists(index: described_class::INDEX_ALIAS)).to eq(true)
|
||||
end
|
||||
|
||||
it "adds custom alias to elasticsearch index with INDEX_NAME" do
|
||||
other_alias = "random"
|
||||
expect(SearchClient.indices.exists(index: other_alias)).to eq(false)
|
||||
described_class.add_alias(index_name: described_class::INDEX_NAME, index_alias: other_alias)
|
||||
expect(SearchClient.indices.exists(index: other_alias)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe "::update_mappings" do
|
||||
it "updates index mappings for classified_listing index", :aggregate_failures do
|
||||
other_name = "random"
|
||||
described_class.create_index(index_name: other_name)
|
||||
initial_mapping = SearchClient.indices.get_mapping(index: other_name).dig(other_name, "mappings")
|
||||
expect(initial_mapping).to be_empty
|
||||
|
||||
described_class.update_mappings(index_alias: other_name)
|
||||
mapping = SearchClient.indices.get_mapping(index: other_name).dig(other_name, "mappings")
|
||||
expect(mapping.deep_stringify_keys).to include(described_class.send("mappings").deep_stringify_keys)
|
||||
|
||||
# Have to cleanup index since it wont automatically be handled by our cluster class bc of the unexpected name
|
||||
described_class.delete_index(index_name: other_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue