130 lines
3.2 KiB
Ruby
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
|