Django Elasticsearch DSL TransportError для картографов разных типов - PullRequest
0 голосов
/ 14 ноября 2018

Я работаю над проектом, использующим Python (3.6), Django (2.1), ElasticSearch (5.1.1) и Elasticsearch-dsl (5.4.0), в котором мне нужно реализовать функцию поиска.

Вот то, что я попробовал:

Из models.py:

class searchdatamodel(models.Model):
    id = models.IntegerField(null=False, primary_key=True)
    company_name = models.TextField(blank=True, null=True)
    city = models.TextField(blank=True, null=True)
    state = models.TextField(blank=True, null=True)
    zip_codes = models.TextField(blank=True, null=True)
    street_address = models.TextField(blank=True, null=True)
    street_address_zip = models.TextField(blank=True, null=True)
    county = models.TextField(blank=True, null=True)
    phone_number = models.DecimalField(max_digits=65535, decimal_places=65535, blank=True, null=True)
    fax_number = models.DecimalField(max_digits=65535, decimal_places=65535, blank=True, null=True)
    web_address = models.TextField(blank=True, null=True)
    last_name = models.TextField(blank=True, null=True)
    first_name = models.TextField(blank=True, null=True)
    contact_title = models.TextField(blank=True, null=True)
    contact_gender = models.TextField(blank=True, null=True)
    actual_employee_size = models.IntegerField(blank=True, null=True)
    employee_size_range = models.TextField(blank=True, null=True)
    actual_sales_volume = models.IntegerField(blank=True, null=True)
    sales_volume_range = models.TextField(blank=True, null=True)
    primary_sic = models.IntegerField(blank=True, null=True)
    primary_sic_description = models.TextField(blank=True, null=True)
    secondary_sic_1 = models.IntegerField(blank=True, null=True)
    secondary_sic_description_1 = models.TextField(blank=True, null=True)
    secondary_sic_2 = models.IntegerField(blank=True, null=True)
    secondary_sic_description_2 = models.TextField(blank=True, null=True)
    credit_alpha_score = models.TextField(blank=True, null=True)
    credit_numeric_score = models.IntegerField(blank=True, null=True)
    headquarters_branch = models.TextField(blank=True, null=True)
    square_footage = models.TextField(blank=True, null=True)
    registry_date = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'searchdatamodel'

    # Implement indexing for SearchDataModel model
    def indexing(self):
        SearchDataIndex.init()
        obj = SearchDataIndex(
            id=self.id,
            company_name=self.company_name,
            city=self.city,
            state=self.state,
            zip_code=self.zip_codes,
            street_address=self.street_address,
            street_address_zip=self.street_address_zip,
            county=self.county,
            phone_number=self.phone_number,
            fax_number=self.fax_number,
            web_address=self.web_address,
            last_name=self.last_name,
            first_name=self.first_name,
            contact_title=self.contact_title,
            contact_gender=self.contact_gender,
            actual_employee_size=self.actual_employee_size,
            actual_sales_volume=self.actual_sales_volume,
            primary_sic=self.primary_sic,
            primary_sic_description=self.primary_sic_description,
            registry_date=self.registry_date
        )
        obj.save()
        return obj.to_dict(include_meta=True)

Из serach.py:

class SearchDataIndex(DocType):
    id = Integer()
    company_name = Text()
    city = Text()
    state = Text()
    zip_codes = Text()
    street_address = Text()
    street_address_zip = Integer()
    county = Text()
    phone_number = Text()
    fax_number = Text()
    web_address = Text()
    last_name = Text()
    first_name = Text()
    contact_title = Text()
    contact_gender = Text()
    actual_employee_size = Integer()
    actual_sales_volume = Text()
    primary_sic = Text()
    primary_sic_description = Text()
    registry_date = Date()

    class Meta:
        index = 'data-search'

    # A method for bulk indexing
    def bulk_indexing():
        SearchDataIndex.init()
        es = Elasticsearch()
        bulk(client=es, actions=(b.indexing() for b in
                        models.searchdatamodel.objects.all().iterator()))

Когда я пытался запустить функцию bulk_indexing, она возвращает ошибку, как показано ниже:

Файл "/Users/abdul/PycharmProjects/Dmitry/DVirEnv/lib/python3.6/site-packages/elasticsearch/connection/base.py ", строка 125, в _raise_error повысить HTTP_EXCEPTIONS.get (status_code, TransportError) (status_code, error_message, Additional_info)

asticsearch.exceptions.RequestError: TransportError (400,'ception_argument, 'mapper [zip_codes] другого типа, current_type [integer], merged_type [text]')

Я пытался изменить тип zip_code на IntegerField в модели, но безуспешно.

Что тут может быть не так?

Заранее спасибо!

1 Ответ

0 голосов
/ 06 января 2019

К сожалению, вы не можете просто так изменить тип. Вам придется повторно сопоставить индекс, который просто удаляет индекс и затем снова запускает функцию отображения.

Чтобы удалить индекс, запустите

es = Elasticsearch()
es.indices.delete(index='data-search')

А затем сопоставьте индекс, снова запустив массовый индексатор.

Примечание. Любые существующие данные сохранят старый тип данных, поэтому, если вам нужно сохранить данные, но изменить тип данных, это совсем другая червь, включающий создание новой версии индекса и чтение старых данных в него.

...