docs: def search(self, search_string, **opt):
      """The core function of the package. These are the arguments we consider.
  
  
      Args:
          search_string (str): This is what you are looking for in your pony database.
      Optional Args:
          opt: The following opts are available for the search function:
          * add_wildcars(bool): This opt allows you to search no literal queries.
          * fields: This opt let you filter your search result on some model by the fields you want to search.
          * include_entity: This opt let you see not only the result and the register fields but all the instance from the entity of the database.
          * except_fields: Tell the searcher to not look on these fields.
          * use_dict: This option let you activate the dict for the items in the search result, or just view them as a list.
          We implement this because we wanted that the  first field registered of the model would be the most important one.
          As was explained in the IndexView section.
      Returns:
          (dict): A python dictionary with the results for the model.
      """
  
      prepped_string = self.prep_search_string(
          search_string
        , self.to_bool(opt.get('add_wildcards', False))
        )
  
      with self._whoosh.searcher() as searcher:
        fields = opt.get('fields', self._schema.names())
        fields = [x for x in fields if len(x) > 0]
  
        field = opt.get('field', '')
        if len(field) > 0:
          if isinstance(field, str) or isinstance(field, str):
            fields = [field]
          elif isinstance(field, list):
            fields = fields + field
  
        fields = [x for x in fields if len(x) > 0]
  
        if len(fields) == 0:
          fields = self._schema.names()
  
        if len(fields) > 0:
          fields = set(fields) & set(self._schema.names())
          fields = list(fields)
  
        except_fields = opt.get('except_fields', [])
        except_fields = [x for x in except_fields if len(x) > 0]
  
        if len(except_fields) > 0:
          fields = list(set(fields) - set(except_fields))
  
        parser = qparser.MultifieldParser(
            fields, self._whoosh.schema
          , group=opt.get('group', qparser.OrGroup)
          )
  
        query       = parser.parse(prepped_string)
        search_opts = self.parse_opts_searcher(opt, self._parameters)
        results     = searcher.search(query, terms=True, **search_opts)
  
        ma = defaultdict(set)
        for f, term in results.matched_terms():
          ma[f].add(term)
  
        dic = {
            'runtime'       : results.runtime
          , 'cant_results'  : results.estimated_length()
          , 'matched_terms' : {k: list(v) for k, v in list(ma.items())}
          , 'facet_names'   : results.facet_names()
          }
  
        if dic['cant_results'] == 0 and self.to_bool(opt.get('something', False)):
          opt['add_wildcards'] = True
          opt['something']     = False
          return self.search(search_string, **opt)
  
        value_results = {}
  
        for r in results:
          params = {k:r[k] for k in self._primary_key}
          ans = {
              'docnum' : r.docnum
            , 'pk'     : tuple(params.values())
            , 'score'  : r.score
          }
  
          if self.to_bool(opt.get('include_entity', False)):
            entity     = self._model.get(**params)
            dic_entity = entity.to_dict()
  
            if opt.get('use_dict', True):
              ans['entity'] = dic_entity
            else:
              fields_missing      = set(dic_entity.keys()) - set(self._fields)
              ans['other_fields'] = [(k, dic_entity[k]) for k in fields_missing]
              ans['entity']       = [(k, dic_entity[k]) for k in self._fields]
            ans['model'] = self._name
          value_results[ans['pk']] = ans
  
        dic["results"] = list(value_results.values())
        return dic