2017-10-21 25 views
0

Nous utilisons Django MarkupField pour stocker le texte Markdown et cela fonctionne plutôt bien.indexation des champs de modèles personnalisés de Django dans wagtail

Cependant, lorsque nous essayons d'indexer ces champs Bergeronnette nous obtenons des erreurs de sérialisation de ElasticSearch, comme ceci:

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'>)",)) 

Une solution consiste à appelables d'index qui renvoient field.raw mais nous aurions dû écrire un tel appelable pour chaque propriété de champ Markdown que nous avons dans nos modèles. Je pensais que nous pourrions contourner cela en étendant la propriété de champ (c'est-à-dire, la classe django-markupfield Markup qui remplace le MarkupField) avec une méthode get_searchable_content(value) mais les erreurs de sérialisation persistent.

Quelqu'un a-t-il des astuces pour indexer des champs Django personnalisés dans Wagtail + elasticsearch?

Répondre

0

je mettais le get_searchable_content au mauvais endroit, je pensais qu'il était nécessaire dans la classe Markup mais il doit être placé sur la classe modèle Field Django lui-même. Wagtail va alors extraire la valeur appropriée à indexer dans elasticsearch (ou tout autre backend de recherche).

La solution la plus simple consistait à étendre MarkupField avec une classe Field personnalisée et à ajouter un get_searchable_content(self, value) qui délègue son implémentation à MarkupField.get_prep_value.

2

Il y a plusieurs façons de le faire. Le mieux serait de créer votre propre champ en elasticsearch-dsl, voir (0) par exemple, et l'utiliser pour la (dé) sérialisation. Une autre option consiste à créer votre propre sous-classe JSONSerializer (1) et à la transmettre sous la forme serializer=MyJSONSerializer() dans le constructeur Elasticsearch, qui peut traiter des objets markupfield.fields.Markup.

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