mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
* Initial work on new search backend * Clean up search backends * Return only the most relevant result per object * Clear any pre-existing cached entries on cache() * #6003: Implement global search functionality for custom field values * Tweak field weights & document guidance * Extend search() to accept a lookup type * Move get_registry() out of SearchBackend * Enforce object permissions when returning search results * Add indexers for remaining models * Avoid calling remove() on non-cacheable objects * Use new search backend by default * Extend search backend to filter by object type * Clean up search view form * Enable specifying lookup logic * Add indexes for value field * Remove object type selector from search bar * Introduce SearchTable and enable HTMX for results * Enable pagination * Remove legacy search backend * Cleanup * Use a UUID for CachedValue primary key * Refactoring search methods * Define max search results limit * Extend reindex command to support specifying particular models * Add clear() and size to SearchBackend * Optimize bulk caching performance * Highlight matched portion of field value * Performance improvements for reindexing * Started on search tests * Cleanup & docs * Documentation updates * Clean up SearchIndex * Flatten search registry to register by app_label.model_name * Clean up search backend classes * Clean up RestrictedGenericForeignKey and RestrictedPrefetch * Resolve migrations conflict
This commit is contained in:
77
netbox/extras/management/commands/reindex.py
Normal file
77
netbox/extras/management/commands/reindex.py
Normal file
@@ -0,0 +1,77 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from extras.registry import registry
|
||||
from netbox.search.backends import search_backend
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Reindex objects for search'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'args',
|
||||
metavar='app_label[.ModelName]',
|
||||
nargs='*',
|
||||
help='One or more apps or models to reindex',
|
||||
)
|
||||
|
||||
def _get_indexers(self, *model_names):
|
||||
indexers = {}
|
||||
|
||||
# No models specified; pull in all registered indexers
|
||||
if not model_names:
|
||||
for idx in registry['search'].values():
|
||||
indexers[idx.model] = idx
|
||||
|
||||
# Return only indexers for the specified models
|
||||
else:
|
||||
for label in model_names:
|
||||
try:
|
||||
app_label, model_name = label.lower().split('.')
|
||||
except ValueError:
|
||||
raise CommandError(
|
||||
f"Invalid model: {label}. Model names must be in the format <app_label>.<model_name>."
|
||||
)
|
||||
try:
|
||||
idx = registry['search'][f'{app_label}.{model_name}']
|
||||
indexers[idx.model] = idx
|
||||
except KeyError:
|
||||
raise CommandError(f"No indexer registered for {label}")
|
||||
|
||||
return indexers
|
||||
|
||||
def handle(self, *model_labels, **kwargs):
|
||||
|
||||
# Determine which models to reindex
|
||||
indexers = self._get_indexers(*model_labels)
|
||||
if not indexers:
|
||||
raise CommandError("No indexers found!")
|
||||
self.stdout.write(f'Reindexing {len(indexers)} models.')
|
||||
|
||||
# Clear all cached values for the specified models
|
||||
self.stdout.write('Clearing cached values... ', ending='')
|
||||
self.stdout.flush()
|
||||
content_types = [
|
||||
ContentType.objects.get_for_model(model) for model in indexers.keys()
|
||||
]
|
||||
deleted_count = search_backend.clear(content_types)
|
||||
self.stdout.write(f'{deleted_count} entries deleted.')
|
||||
|
||||
# Index models
|
||||
self.stdout.write('Indexing models')
|
||||
for model, idx in indexers.items():
|
||||
app_label = model._meta.app_label
|
||||
model_name = model._meta.model_name
|
||||
self.stdout.write(f' {app_label}.{model_name}... ', ending='')
|
||||
self.stdout.flush()
|
||||
i = search_backend.cache(model.objects.iterator(), remove_existing=False)
|
||||
if i:
|
||||
self.stdout.write(f'{i} entries cached.')
|
||||
else:
|
||||
self.stdout.write(f'None found.')
|
||||
|
||||
msg = f'Completed.'
|
||||
if total_count := search_backend.size:
|
||||
msg += f' Total entries: {total_count}'
|
||||
self.stdout.write(msg, self.style.SUCCESS)
|
Reference in New Issue
Block a user