Add Elasticsearch index for classified_listings (#6031) [deploy]

This commit is contained in:
Alex 2020-02-12 15:24:01 -08:00 committed by GitHub
parent ee5aa1ff1a
commit 0f32eb9db0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 221 additions and 1 deletions

View 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

View file

@ -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

View 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