diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 2c1afab520..ddc6c4108d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -14,6 +14,7 @@ Changelog * Project template updated to Django 1.7 * 'boost' applied to the title field on searches reduced from 100 to 2 * The 'type' method of PageQuerySet (used to filter the queryset to a specific page type) now includes subclasses of the given page type. + * The 'update_index' management command now updates all backends listed in WAGTAILSEARCH_BACKENDS, or a specific one passed on the command line, rather than just the default backend * Fix: 'wagtail start' command now works on Windows * Fix: The external image URL generator no longer stores generated images in Django's cache * Fix: Elasticsearch backend can now search querysets that have been filtered with an 'in' clause of a non-list type (such as a ValuesListQuerySet) diff --git a/docs/reference/management_commands.rst b/docs/reference/management_commands.rst index 18358a8699..9daffaccef 100644 --- a/docs/reference/management_commands.rst +++ b/docs/reference/management_commands.rst @@ -47,7 +47,7 @@ Options: update_index ------------ -:code:`./manage.py update_index` +:code:`./manage.py update_index [--backend ]` This command rebuilds the search index from scratch. It is only required when using Elasticsearch. @@ -59,6 +59,24 @@ It is recommended to run this command once a week and at the following times: The search may not return any results while this command is running, so avoid running it at peak times. +Specifying which backend to update +`````````````````````````````````` + +.. versionadded:: 0.7 + + +By default, ``update_index`` will rebuild all the search indexes listed in ``WAGTAILSEARCH_BACKENDS``. + +If you have multiple backends and would only like to update one of them, you can use the ``--backend`` option. + +For example, to update just the default backend: + +.. code-block:: + + python manage.py update_index --backend default + + + .. _search_garbage_collect: search_garbage_collect diff --git a/docs/releases/0.7.rst b/docs/releases/0.7.rst index 17bde9b59a..3f9f704d39 100644 --- a/docs/releases/0.7.rst +++ b/docs/releases/0.7.rst @@ -32,6 +32,7 @@ Minor features * The project template (used when running ``wagtail start``) has been updated to Django 1.7. * The 'boost' applied to the title field on searches has been reduced from 100 to 2. * The ``type`` method of ``PageQuerySet`` (used to filter the queryset to a specific page type) now includes subclasses of the given page type. + * The ``update_index`` management command now updates all backends listed in ``WAGTAILSEARCH_BACKENDS``, or a specific one passed on the command line, rather than just the default backend. Bug fixes ~~~~~~~~~ diff --git a/wagtail/wagtailsearch/management/commands/update_index.py b/wagtail/wagtailsearch/management/commands/update_index.py index d03ed1c6b3..2c9002c4ae 100644 --- a/wagtail/wagtailsearch/management/commands/update_index.py +++ b/wagtail/wagtailsearch/management/commands/update_index.py @@ -1,12 +1,15 @@ +from optparse import make_option + from django.core.management.base import BaseCommand from django.db import models +from django.conf import settings from wagtail.wagtailsearch.indexed import Indexed from wagtail.wagtailsearch.backends import get_search_backend class Command(BaseCommand): - def handle(self, **options): + def get_object_list(self): # Print info self.stdout.write("Getting object list") @@ -41,26 +44,57 @@ class Command(BaseCommand): # Space free, take it object_set[key] = obj - # Search backend - if 'backend' in options: - s = options['backend'] - else: - s = get_search_backend() + return indexed_models, object_set.values() + + def update_backend(self, backend_name, models, object_list): + # Print info + self.stdout.write("Updating backend: " + backend_name) + + # Get backend + backend = get_search_backend(backend_name) # Reset the index - self.stdout.write("Reseting index") - s.reset_index() + self.stdout.write(backend_name + ": Reseting index") + backend.reset_index() # Add types - self.stdout.write("Adding types") - for model in indexed_models: - s.add_type(model) + self.stdout.write(backend_name + ": Adding types") + for model in models: + backend.add_type(model) # Add objects to index - self.stdout.write("Adding objects") - for result in s.add_bulk(object_set.values()): + self.stdout.write(backend_name + ": Adding objects") + for result in backend.add_bulk(object_list): self.stdout.write(result[0] + ' ' + str(result[1])) # Refresh index - self.stdout.write("Refreshing index") - s.refresh_index() + self.stdout.write(backend_name + ": Refreshing index") + backend.refresh_index() + + option_list = BaseCommand.option_list + ( + make_option('--backend', + action='store', + dest='backend_name', + default=None, + help="Specify a backend to update", + ), + ) + + def handle(self, **options): + # Get object list + models, object_list = self.get_object_list() + + # Get list of backends to index + if options['backend_name']: + # index only the passed backend + backend_names = [options['backend_name']] + elif hasattr(settings, 'WAGTAILSEARCH_BACKENDS'): + # index all backends listed in settings + backend_names = settings.WAGTAILSEARCH_BACKENDS.keys() + else: + # index the 'default' backend only + backend_names = ['default'] + + # Update backends + for backend_name in backend_names: + self.update_backend(backend_name, models, object_list) diff --git a/wagtail/wagtailsearch/tests/test_backends.py b/wagtail/wagtailsearch/tests/test_backends.py index 903f59608f..471426c195 100644 --- a/wagtail/wagtailsearch/tests/test_backends.py +++ b/wagtail/wagtailsearch/tests/test_backends.py @@ -20,6 +20,7 @@ class BackendTests(WagtailTestUtils): for backend_name, backend_conf in settings.WAGTAILSEARCH_BACKENDS.items(): if backend_conf['BACKEND'] == self.backend_path: self.backend = get_search_backend(backend_name) + self.backend_name = backend_name break else: # no conf entry found - skip tests for this backend @@ -153,7 +154,7 @@ class BackendTests(WagtailTestUtils): # Run update_index command with self.ignore_deprecation_warnings(): # ignore any DeprecationWarnings thrown by models with old-style indexed_fields definitions - management.call_command('update_index', backend=self.backend, interactive=False, stdout=StringIO()) + management.call_command('update_index', backend_name=self.backend_name, interactive=False, stdout=StringIO()) # Check that there are still 3 results results = self.backend.search("Hello", models.SearchTest)