2017-10-21 3 views
0

Wir verwenden Django MarkupField zu MarkDown Text speichern und es funktioniert ganz gut.Indizierung benutzerdefinierte Django Modell Felder in der Bachstelze

Wenn wir jedoch zu indizieren diese Felder in Bachstelze versuchen bekommen wir Serialisierung Fehler von Elasticsearch, wie folgt aus:

File "/usr/local/lib/python3.5/dist-packages/wagtail/wagtailsearch/management/commands/update_index.py", line 120, in handle 
    self.update_backend(backend_name, schema_only=options.get('schema_only', False)) 
File "/usr/local/lib/python3.5/dist-packages/wagtail/wagtailsearch/management/commands/update_index.py", line 87, in update_backend 
    index.add_items(model, chunk) 
File "/usr/local/lib/python3.5/dist-packages/wagtail/wagtailsearch/backends/elasticsearch.py", line 579, in add_items 
    bulk(self.es, actions) 
File "/usr/local/lib/python3.5/dist-packages/elasticsearch/helpers/__init__.py", line 195, in bulk 
    for ok, item in streaming_bulk(client, actions, **kwargs): 
File "/usr/local/lib/python3.5/dist-packages/elasticsearch/helpers/__init__.py", line 162, in streaming_bulk 
    for bulk_actions in _chunk_actions(actions, chunk_size, max_chunk_bytes, client.transport.serializer): 
File "/usr/local/lib/python3.5/dist-packages/elasticsearch/helpers/__init__.py", line 61, in _chunk_actions 
    data = serializer.dumps(data) 
File "/usr/local/lib/python3.5/dist-packages/elasticsearch/serializer.py", line 50, in dumps 
    raise SerializationError(data, e) 
elasticsearch.exceptions.SerializationError: ({'_partials': [<markupfield.fields.Markup object at 0x7faa6e238e80>, <markupfield.fields.Markup object at 0x7faa6dbc4da0>], 'pk': '1', 'research_interests': <markupfield.fields.Markup object at 0x7faa6e238e80>, 'bio': <markupfield.fields.Markup object at 0x7faa6dbc4da0>}, TypeError("Unable to serialize <markupfield.fields.Markup object at 0x7faa6e238e80> (type: <class 'markupfield.fields.Markup'>)",)) 

Eine Abhilfe zu indizieren Callables ist die field.raw zurück, aber dann würden wir ein schreiben müssen so aufrufbar für jede Markdown-Eigenschaft, die wir in unseren Modellen haben. Ich dachte, wir könnten das umgehen, indem wir die Feldeigenschaft (d. H. Die Klasse django-markupfield Markup, die die MarkupField ersetzt) ​​durch eine get_searchable_content(value)-Methode erweitern, aber die Serialisierungsfehler bleiben bestehen.

Hat jemand irgendwelche Tipps zur Indizierung von benutzerdefinierten Django-Felder in Wagtail + elasticsearch?

Antwort

0

ich die get_searchable_content an der falschen Stelle setzen, dachte ich, es in der Markup Klasse benötigt wurde, sondern es muss auf der Django-Modell Field Klasse selbst platziert werden. Wagtail zieht dann den entsprechenden Wert, der in elasticsearch (oder einem anderen Such-Backend) indiziert werden soll.

Die einfachste Lösung bestand darin, MarkupField mit einer benutzerdefinierten Feldklasse zu erweitern und eine get_searchable_content(self, value) hinzuzufügen, die ihre Implementierung an MarkupField.get_prep_value delegiert.

2

Es gibt mehrere Möglichkeiten, dies zu tun. Das beste wäre, ein eigenes Feld in elasticsearch-dsl zu erstellen, siehe (0) zum Beispiel, und das für (De) Serialisierung zu verwenden. Eine andere Möglichkeit besteht darin, Ihre eigene JSONSerializer (1) Unterklasse zu erstellen und sie als serializer=MyJSONSerializer() im Elasticsearch Konstruktor zu übergeben, die mit markupfield.fields.Markup Objekten umgehen kann.

0-https://github.com/elastic/elasticsearch-dsl-py/blob/master/test_elasticsearch_dsl/test_document.py#L49-L58 1-https://github.com/elastic/elasticsearch-py/blob/master/elasticsearch/serializer.py#L24

Verwandte Themen