# 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