"""``python manage.py search_index`` - manage the Elasticsearch index.""" from __future__ import annotations import json import time from typing import Any from django.core.management.base import BaseCommand, CommandError from apps.search.indexing import alias_name, get_client, rebuild_index class Command(BaseCommand): help = "Create, rebuild, inspect or drop the Elasticsearch profile index." def add_arguments(self, parser) -> None: # noqa: ANN001 group = parser.add_mutually_exclusive_group(required=True) group.add_argument("--rebuild", action="store_true", help="Rebuild and swap the alias.") group.add_argument("--status", action="store_true", help="Show index/alias status.") group.add_argument("--drop", action="store_true", help="Delete the index and its alias.") def handle(self, *args: Any, **options: Any) -> None: client = get_client() if not client.ping(): raise CommandError("Elasticsearch is not reachable. Check ELASTICSEARCH_HOSTS.") if options["rebuild"]: started = time.perf_counter() result = rebuild_index(client) result["elapsed_seconds"] = round(time.perf_counter() - started, 2) self.stdout.write(json.dumps(result, indent=2)) self.stdout.write(self.style.SUCCESS("Index rebuilt.")) return alias = alias_name() if options["status"]: exists = client.indices.exists_alias(name=alias) payload: dict[str, Any] = {"alias": alias, "exists": bool(exists)} if exists: indices = list(client.indices.get_alias(name=alias).keys()) payload["indices"] = indices payload["documents"] = client.count(index=alias)["count"] self.stdout.write(json.dumps(payload, indent=2)) return if options["drop"]: if client.indices.exists_alias(name=alias): for name in client.indices.get_alias(name=alias): client.indices.delete(index=name, ignore_unavailable=True) client.indices.delete(index=alias, ignore_unavailable=True) self.stdout.write(self.style.WARNING(f"Dropped index/alias {alias}."))