Execute a find query.
        
        Ref: http://helpdesk.knackhq.com/support/solutions/articles/5000446111-api-reference-root-access#retrieve
        
        :param filter: list of criterions. For more information: 
          http://helpdesk.knackhq.com/support/solutions/articles/5000447623-api-reference-filters-search
        :param sort_field: field_name or field_id, taking field_name by default.
          if using field_id, please set using_name = False.
        :param sort_order: -1 or 1, 1 means ascending, -1 means descending
        :param page and rows_per_page: skip first #page * #rows_per_page, 
          returns #rows_per_page of records. For more information:
          http://helpdesk.knackhq.com/support/solutions/articles/5000444173-working-with-the-api#pagination
        :param using_name: if you are using field_name in filter and sort_field, 
          please set using_name = True (it's the default), otherwise, False
        :param data_only: set True you only need the data or the full api
          response
        :param raw: Default True, set True if you want the data in raw format. 
          Otherwise, html format
        :param recovery_name: Default True, set True if you want field name
          instead of field key
        
        **中文文档**
        
        返回多条记录

def find(self, filter=list(), 
             sort_field=None, sort_order=None, 
             page=None, rows_per_page=None,
             using_name=True, data_only=True, raw=True, recovery_name=True):
        """Execute a find query.
        
        Ref: http://helpdesk.knackhq.com/support/solutions/articles/5000446111-api-reference-root-access#retrieve
        
        :param filter: list of criterions. For more information: 
          http://helpdesk.knackhq.com/support/solutions/articles/5000447623-api-reference-filters-search
        :param sort_field: field_name or field_id, taking field_name by default.
          if using field_id, please set using_name = False.
        :param sort_order: -1 or 1, 1 means ascending, -1 means descending
        :param page and rows_per_page: skip first #page * #rows_per_page, 
          returns #rows_per_page of records. For more information:
          http://helpdesk.knackhq.com/support/solutions/articles/5000444173-working-with-the-api#pagination
        :param using_name: if you are using field_name in filter and sort_field, 
          please set using_name = True (it's the default), otherwise, False
        :param data_only: set True you only need the data or the full api
          response
        :param raw: Default True, set True if you want the data in raw format. 
          Otherwise, html format
        :param recovery_name: Default True, set True if you want field name
          instead of field key
        
        **中文文档**
        
        返回多条记录
        """
        if using_name:            
            for criterion in filter:
                criterion["field"] = self.get_field_key(criterion["field"])
            
            if sort_field:
                sort_field = self.get_field_key(sort_field)
            
        if sort_order is None:
            pass
        elif sort_order == 1:
            sort_order = "asc"
        elif sort_order == -1:
            sort_order = "desc"
        else:
            raise ValueError
        
        params = dict()
        if len(filter) >= 1:
            params["filters"] = json.dumps(filter)
        
        if sort_field:
            params["sort_field"] = sort_field
            params["sort_order"] = sort_order
        
        if (page is not None) \
            and (rows_per_page is not None) \
            and isinstance(page, int) \
            and isinstance(rows_per_page, int) \
            and (page >= 1) \
            and (rows_per_page >= 1):
            params["page"] = page
            params["rows_per_page"] = rows_per_page
            
        res = self.get(self.get_url, params)
        
        # handle data_only and recovery
        if data_only:
            try:
                res = res["records"]
                if raw:
                    res = [self.get_raw_values(data, recovery_name) for data in res]
                else:
                    res = [self.get_html_values(data, recovery_name) for data in res]
            except KeyError:
                pass
        else:
            if raw:
                try:
                    res["records"] = [
                        self.get_raw_values(data, recovery_name) for data in res["records"]]
                except KeyError:
                    pass
            else:
                try:
                    res["records"] = [
                        self.get_html_values(data, recovery_name) for data in res["records"]]
                except KeyError:
                    pass
        return res