<commit_before>from .connections import connections
from .search import Search
from .exceptions import IllegalOperation
from .mapping import Mapping
from .utils import merge
from . import analysis

DEFAULT_DOC_TYPE = 'doc'

class IndexTemplate(object):
    def __init__(self, name, template, index=None, **kwargs):
        if index is None:
            self._index = Index(template, **kwargs)
        else:
            if kwargs:
                raise ValueError("You cannot specify options for Index when"
                                 " passing an Index instance.")
            self._index = index.clone()
            self._index._name = template
        self._template_name = name

    def __getattr__(self, attr_name):
        return getattr(self._index, attr_name)

    def to_dict(self):
        d = self._index.to_dict()
        d['index_patterns'] = [self._index._name]
        return d

    def save(self, using=None):
        es = connections.get_connection(using or self._index._using)
        es.indices.put_template(name=self._template_name, body=self.to_dict())

class Index(object):
    def __init__(self, name, doc_type=DEFAULT_DOC_TYPE, using='default'):
        """
        :arg name: name of the index
        :arg using: connection alias to use, defaults to ``'default'``
        """
        self._name = name
        self._doc_types = []
        self._using = using
        self._settings = {}
        self._aliases = {}
        self._analysis = {}
        self._mapping = None
        if doc_type is not DEFAULT_DOC_TYPE:
            self._mapping = Mapping(doc_type)

    def _get_doc_type(self):
        if self._mapping is not None:
            return self._mapping.doc_type
        for d in self._doc_types:
            return d._doc_type.name
        return None

    def get_or_create_mapping(self, doc_type=DEFAULT_DOC_TYPE):
        if self._mapping is None:
            self._mapping = Mapping(doc_type)
        return self._mapping

    def as_template(self, template_name, pattern=None):
        # TODO: should we allow pattern to be a top-level arg?
        # or maybe have an IndexPattern that allows for it and have
        # Document._index be that?
        return IndexTemplate(template_name, pattern or self._name, index=self)

    def resolve_field(self, field_path):
        for doc in self._doc_types:
            field = doc._doc_type.mapping.resolve_field(field_path)
            if field is not None:
                return field
        return self.get_or_create_mapping().resolve_field(field_path)

    def load_mappings(self, using=None):
        self.get_or_create_mapping().update_from_es(self._name, using=using or self._using)

    def clone(self, name=None, doc_type=None, using=None):
        """
        Create a copy of the instance with another name or connection alias.
        Useful for creating multiple indices with shared configuration::

            i = Index('base-index')
            i.settings(number_of_shards=1)
            i.create()

            i2 = i.clone('other-index')
            i2.create()

        :arg name: name of the index
        :arg using: connection alias to use, defaults to ``'default'``
        """
        doc_type = doc_type or self._get_doc_type() or DEFAULT_DOC_TYPE
        i = Index(name or self._name,
                  doc_type=doc_type,
                  using=using or self._using)
        i._settings = self._settings.copy()
        i._aliases = self._aliases.copy()
        i._analysis = self._analysis.copy()
        i._doc_types = self._doc_types[:]
        if self._mapping is not None:
            i._mapping = self._mapping._clone()<commit_msg>Don't create a mapping when resolving a field<commit_after>from .connections import connections
from .search import Search
from .exceptions import IllegalOperation
from .mapping import Mapping
from .utils import merge
from . import analysis

DEFAULT_DOC_TYPE = 'doc'

class IndexTemplate(object):
    def __init__(self, name, template, index=None, **kwargs):
        if index is None:
            self._index = Index(template, **kwargs)
        else:
            if kwargs:
                raise ValueError("You cannot specify options for Index when"
                                 " passing an Index instance.")
            self._index = index.clone()
            self._index._name = template
        self._template_name = name

    def __getattr__(self, attr_name):
        return getattr(self._index, attr_name)

    def to_dict(self):
        d = self._index.to_dict()
        d['index_patterns'] = [self._index._name]
        return d

    def save(self, using=None):
        es = connections.get_connection(using or self._index._using)
        es.indices.put_template(name=self._template_name, body=self.to_dict())

class Index(object):
    def __init__(self, name, doc_type=DEFAULT_DOC_TYPE, using='default'):
        """
        :arg name: name of the index
        :arg using: connection alias to use, defaults to ``'default'``
        """
        self._name = name
        self._doc_types = []
        self._using = using
        self._settings = {}
        self._aliases = {}
        self._analysis = {}
        self._mapping = None
        if doc_type is not DEFAULT_DOC_TYPE:
            self._mapping = Mapping(doc_type)

    def _get_doc_type(self):
        if self._mapping is not None:
            return self._mapping.doc_type
        for d in self._doc_types:
            return d._doc_type.name
        return None

    def get_or_create_mapping(self, doc_type=DEFAULT_DOC_TYPE):
        if self._mapping is None:
            self._mapping = Mapping(doc_type)
        return self._mapping

    def as_template(self, template_name, pattern=None):
        # TODO: should we allow pattern to be a top-level arg?
        # or maybe have an IndexPattern that allows for it and have
        # Document._index be that?
        return IndexTemplate(template_name, pattern or self._name, index=self)

    def resolve_field(self, field_path):
        for doc in self._doc_types:
            field = doc._doc_type.mapping.resolve_field(field_path)
            if field is not None:
                return field
        if self._mapping:
            return self._mapping.resolve_field(field_path)
        return None

    def load_mappings(self, using=None):
        self.get_or_create_mapping().update_from_es(self._name, using=using or self._using)

    def clone(self, name=None, doc_type=None, using=None):
        """
        Create a copy of the instance with another name or connection alias.
        Useful for creating multiple indices with shared configuration::

            i = Index('base-index')
            i.settings(number_of_shards=1)
            i.create()

            i2 = i.clone('other-index')
            i2.create()

        :arg name: name of the index
        :arg using: connection alias to use, defaults to ``'default'``
        """
        doc_type = doc_type or self._get_doc_type() or DEFAULT_DOC_TYPE
        i = Index(name or self._name,
                  doc_type=doc_type,
                  using=using or self._using)
        i._settings = self._settings.copy()
        i._aliases = self._aliases.copy()
        i._analysis = self._analysis.copy()
        i._doc_types = self._doc_types[:]
        if self._mapping is not None:
            i._mapping = self._mapping._clone()
{'fraction_non_alphanumeric': 0.08960281957435272, 'fraction_numerical': 0.0008133387555917039, 'mean_word_length': 2.231712658782304, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5494050', 'n_tokens_mistral': 2062, 'n_tokens_neox': 2019, 'n_words': 584}