def expected_fields(cls, include_nullable=True): """ Returns a list of fields we expect to be present in the mapping and in the extraction method. Should be updated whenever you change the mapping to add/remove fields. """ # Fields that can not be directly compared with the property of the # same name on the Addon instance, either because the property doesn't # exist on the model, or it has a different name, or the value we need # to store in ES differs from the one in the db. complex_fields = [ 'app', 'boost', 'category', 'colors', 'current_version', 'description', 'has_eula', 'has_privacy_policy', 'listed_authors', 'name', 'platforms', 'previews', 'ratings', 'summary', 'tags', ] # Fields that need to be present in the mapping, but might be skipped # for extraction because they can be null. nullable_fields = [] # For each translated field that needs to be indexed, we store one # version for each language we have an analyzer for. _indexed_translated_fields = ('name', 'description', 'summary') analyzer_fields = list(chain.from_iterable( [['%s_l10n_%s' % (field, lang) for lang, analyzer in SEARCH_LANGUAGE_TO_ANALYZER.items()] for field in _indexed_translated_fields])) # It'd be annoying to hardcode `analyzer_fields`, so we generate it, # but to make sure the test is correct we still do a simple check of # the length to make sure we properly flattened the list. assert len(analyzer_fields) == (len(SEARCH_LANGUAGE_TO_ANALYZER) * len(_indexed_translated_fields)) # Each translated field that we want to return to the API. raw_translated_fields = [ '%s_translations' % field for field in ['name', 'description', 'developer_comments', 'homepage', 'summary', 'support_email', 'support_url']] # Return a list with the base fields and the dynamic ones added. fields = (cls.simple_fields + complex_fields + analyzer_fields + raw_translated_fields) if include_nullable: fields += nullable_fields return fields
def attach_language_specific_analyzers(cls, mapping, field_names): """ For each field in field_names, attach language-specific mappings that will use specific analyzers for these fields in every language that we support. These mappings are used by the search filtering code if they exist. """ doc_name = cls.get_doctype_name() for lang, analyzer in SEARCH_LANGUAGE_TO_ANALYZER.items(): for field in field_names: property_name = '%s_l10n_%s' % (field, lang) mapping[doc_name]['properties'][property_name] = { 'type': 'text', 'analyzer': analyzer, }
def attach_language_specific_analyzers_with_raw_variant( cls, mapping, field_names): """ Like attach_language_specific_analyzers() but with an extra field to storethe "raw" variant of the value, for exact matches. """ doc_name = cls.get_doctype_name() for lang, analyzer in SEARCH_LANGUAGE_TO_ANALYZER.items(): for field in field_names: property_name = '%s_l10n_%s' % (field, lang) mapping[doc_name]['properties'][property_name] = { 'type': 'text', 'analyzer': analyzer, 'fields': { 'raw': cls.get_raw_field_definition(), } }