Skip to content

Commit

Permalink
Merge pull request #430 from ox-it/index-list-names-1919
Browse files Browse the repository at this point in the history
Index list names - task #1919
  • Loading branch information
sp-oxford committed Apr 26, 2016
2 parents 1922c09 + 688c989 commit bd4d537
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 24 deletions.
6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@ Type the following command at the root of your project directory:

docker-compose run web python manage.py migrate --settings=talks.settings_docker

### Creating the solr collection

Type the following command to create the solr collection:

docker exec -it --user=solr talksox_solr_1 bin/solr create_core -c collection1

### Creating a user account

Type the following command at the root of your project directory:
Expand Down
4 changes: 3 additions & 1 deletion solr/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
FROM solr
FROM makuk66/docker-solr:4.10.4

ADD ./talks/conf/schema.xml /opt/solr/example/solr/collection1/conf/schema.xml
ADD ./talks/conf/solrconfig.xml /opt/solr/example/solr/collection1/conf/solrconfig.xml
ADD ./talks/conf/stopwords.txt /opt/solr/example/solr/collection1/conf/stopwords.txt
ADD ./talks/conf/lang /opt/solr/example/solr/collection1/conf/lang/

# CMD ["/bin/bash", "-c", "cd /opt/solr/example; java -jar start.jar"]

EXPOSE 8983
19 changes: 5 additions & 14 deletions solr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,21 @@

## Solr schema

The solr schema needs to be generated by using the following command:
If any changes are made to the indexing, the solr schema needs to be regenerated by using the following command:

python manage.py build_solr_schema --settings=talks.local_settings > solr/schema.xml

Every time the `search_indexes.py` files are modified, the `build_solr_schema` command
should be used so that we always have the latest version of the schema in Solr.

## Development

### Using fig

Just type at the root of the repository:

fig up solr

### Using docker

Just type at the root of the repository:

docker build -t talks-solr .
### Using docker-compose

docker run -d -p 8983:8983 talks-solr
Following the instructions on the root README file should bring up the local dev solr instance.

### Using your own installation of Solr
### Using your own installation of Solr (not recommended)

The ``solrconfig.xml`` file is available in the ``solr`` directory at the root of the repository.

Expand Down
5 changes: 4 additions & 1 deletion solr/talks/conf/schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,16 @@

<field name="suggestions" type="textSpell" indexed="true" stored="false" multiValued="true" omitTermFreqAndPositions="true" />

<field name="lists" type="text_en" indexed="true" stored="true" multiValued="true" />

<field name="location_exact" type="string" indexed="true" stored="true" multiValued="false" />

<field name="topics_exact" type="string" indexed="true" stored="true" multiValued="true" />

<field name="group_exact" type="string" indexed="true" stored="true" multiValued="false" />

<field name="lists_exact" type="string" indexed="true" stored="true" multiValued="true" />

<field name="slug" type="text_en" indexed="true" stored="true" multiValued="false" />

<field name="speakers" type="text_en" indexed="true" stored="true" multiValued="true" />
Expand All @@ -188,4 +192,3 @@
<!-- field to use to determine and enforce document uniqueness. -->
<uniqueKey>id</uniqueKey>
</schema>

8 changes: 8 additions & 0 deletions talks/events/search_indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class EventIndex(indexes.SearchIndex, indexes.Indexable):
published = indexes.BooleanField(null=False)
group = indexes.CharField(faceted=True, null=True)
group_slug = indexes.CharField(null=True)
lists = indexes.MultiValueField(faceted=True, null=True)

# suggestions: used for spellchecking
suggestions = indexes.SuggestionField()
Expand Down Expand Up @@ -78,6 +79,10 @@ def prepare(self, obj):
self.prepared_data[self.group.index_fieldname] = obj.group.title
self.prepared_data[self.group_slug.index_fieldname] = obj.group.slug

# lists
lists_names = [list.title for list in obj.public_collections_containing_this_event.all()]
self.prepared_data[self.lists.index_fieldname] = lists_names

suggest_content = [] # used when providing suggestions
full_text_content = [] # used when searching full text

Expand All @@ -97,6 +102,9 @@ def prepare(self, obj):

suggest_content.extend(speakers_names)
full_text_content.extend(speakers_names)

suggest_content.extend(lists_names)
full_text_content.extend(lists_names)

self.prepared_data[self.suggestions.index_fieldname] = suggest_content
self.prepared_data[self.text.index_fieldname] = full_text_content
Expand Down
2 changes: 1 addition & 1 deletion talks/events_search/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
SOLR_TO_NAME = {d['solr_query']: key for key, d in FACET_START_DATE.iteritems()}

sqs = (SearchQuerySet()
.filter(published=True).facet('speakers', mincount=1).facet('location', mincount=1).facet('topics', mincount=1)).facet('group', mincount=1)
.filter(published=True).facet('speakers', mincount=1).facet('location', mincount=1).facet('topics', mincount=1)).facet('group', mincount=1).facet('lists', mincount=1)

# add all the facet start date queries to the queryset
for v in FACET_START_DATE.itervalues():
Expand Down
63 changes: 63 additions & 0 deletions talks/events_search/signal_processor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Custom signal processor for event changes
# If an event is saved, upate it in the default way.
# If a list is saved, update affected events

from talks.events.models import Event
from talks.users.models import Collection, CollectionItem
from django.db import models
from haystack import signals
from haystack.exceptions import NotHandled

class EventUpdateSignalProcessor(signals.BaseSignalProcessor):
def setup(self):
# connect event save/delete to default handler
models.signals.post_save.connect(self.handle_save, sender=Event)
models.signals.post_delete.connect(self.handle_delete, sender=Event)

# connect list save to handler for collection
models.signals.post_save.connect(self.handle_save_list, sender=Collection)
# removing a list treated same as updating it - we just update the affected talks
models.signals.post_delete.connect(self.handle_save_list, sender=Collection)

# update when talk is added/removed from a collection
models.signals.post_save.connect(self.handle_change_collectionItem, sender=CollectionItem)
models.signals.post_delete.connect(self.handle_change_collectionItem, sender=CollectionItem)

def teardown(self):
# disconnect event/collection save/delete
models.signals.post_save.disconnect(self.handle_save, sender=Event)
models.signals.post_delete.disconnect(self.handle_delete, sender=Event)
models.signals.post_save.disconnect(self.handle_save_list, sender=Collection)
models.signals.post_delete.disconnect(self.handle_save_list, sender=Collection)
models.signals.post_save.disconnect(self.handle_change_collectionItem, sender=CollectionItem)
models.signals.post_delete.disconnect(self.handle_change_collectionItem, sender=CollectionItem)

def handle_save_list(self, sender, instance, **kwargs):
# update the each event from the list in each index
events = instance.get_all_events()
using_backends = self.connection_router.for_write(instance=instance)

for event in events.all():
for using in using_backends:
try:
index = self.connections[using].get_unified_index().get_index(event.__class__)
index.update_object(event, using=using)
except Exception:
# TODO: Maybe log it or let the exception bubble?
print "NOT HANDLED"
pass

def handle_change_collectionItem(self, sender, instance, **kwargs):
#re-index the affected event
item = instance.item

using_backends = self.connection_router.for_write(instance=instance)


for using in using_backends:
try:
index = self.connections[using].get_unified_index().get_index(item.__class__)
index.update_object(item, using=using)
except Exception:
print "NOT HANDLED"
pass
3 changes: 2 additions & 1 deletion talks/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@
},
}

HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
HAYSTACK_SIGNAL_PROCESSOR = 'talks.events_search.signal_processor.EventUpdateSignalProcessor'

RAVEN_CONFIG = {
'dsn': 'http://cc958b8c93c340c9a25dd765e1843172:f67c8030f2674d6b9c74718f2abf4c16@sentry.oucs.ox.ac.uk/27',
Expand Down
8 changes: 8 additions & 0 deletions talks/templates/search/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@
{% endfor %}
{% endif %}
</dl>
<dl>
{% if facets.fields.lists %}
<dt>Public Lists</dt>
{% for list in facets.fields.lists|slice:":10" %}
<dd><a href="{{ request.get_full_path }}&amp;selected_facets=lists_exact:{{ list.0|urlencode }}">{{ list.0 }}</a> ({{ list.1 }})</dd>
{% endfor %}
{% endif %}
</dl>
<dl>
{% if facet_date %}
<dt>Start</dt>
Expand Down

0 comments on commit bd4d537

Please sign in to comment.