Websites/app/logical/pool_index.rb

130 lines
3.2 KiB
Ruby

# frozen_string_literal: true
module PoolIndex
module_function
def index_name
"pools_#{Rails.env}"
end
def index_config
{
settings: {
index: {
number_of_shards: 1,
number_of_replicas: 0,
max_result_window: 100_000,
},
},
mappings: {
dynamic: false,
properties: {
id: { type: "integer" },
tags: { type: "keyword" },
name: { type: "text" },
name_kw: { type: "keyword" },
created_at: { type: "date" },
updated_at: { type: "date" },
creator_id: { type: "integer" },
description: { type: "text" },
is_active: { type: "boolean" },
category: { type: "keyword" },
post_ids: { type: "integer" },
post_count: { type: "integer" },
},
},
}
end
def as_indexed_json(pool)
tags = pool.tag_string.split
{
id: pool.id,
tags: tags,
name: pool.name,
name_kw: pool.name,
created_at: pool.created_at,
updated_at: pool.updated_at,
creator_id: pool.creator_id,
description: pool.description,
is_active: pool.is_active,
category: pool.category,
post_ids: pool.post_ids,
post_count: pool.post_ids.size,
}
end
def import!
create_index!(delete_existing: true)
E621::Pool.find_in_batches(batch_size: 1000) do |batch|
batch.map! do |pool|
{
index: {
_id: pool.id,
data: as_indexed_json(pool),
},
}
end
client.bulk(body: batch, index: index_name)
end
end
def create_index!(delete_existing: false)
exists = index_exist?
delete_index! if exists && delete_existing
client.indices.create(index: index_name, body: index_config)
end
def delete_index!
client.indices.delete(index: index_name, ignore: 404)
end
def index_exist?
client.indices.exists(index: index_name)
end
def refresh_index!
client.indices.refresh(index: index_name)
end
def update_document(pool)
client.index(index: index_name, id: pool.id, body: as_indexed_json(pool))
end
def delete_document(id)
client.delete(index: index_name, id: id)
end
def client
@client ||= OpenSearch::Client.new(host: Websites.config.opensearch_host, request_timeout: 120)
end
def search(page, limit, must: [], must_not: [], should: [], order: nil)
page ||= 1
limit ||= 100
query = {
bool: {
must: must,
must_not: must_not,
should: should,
},
}
query[:bool][:minimum_should_match] = 1 if should.any?
query[:bool][:must].push({ match_all: {} }) if query[:bool][:must].empty?
from = (page - 1) * limit
body = {
from: from,
size: limit,
query: query,
sort: order,
_source: false,
timeout: "3000ms",
}
results = client.search(index: index_name, body: body)["hits"]["hits"].map { |hit| hit["_id"].to_i }
count = client.count(index: index_name, body: { query: query })["count"]
{ results: results, count: count }
end
end