<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _search(self, query, fields=None, limit=50000, sampling=None):
 """ Perform the search and return raw rows :type query object :type fields list[str] or None :type limit int :type sampling int or None :arg sampling: Percentage of results to be returned (0,100) :rtype: list """

        body = {
            "query": {
                "bool": {
                    "must": [
                        query
                    ]
                }
            }
        }

        # @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html
        if fields:
            body['_source'] = {
                "includes": fields
            }

        # add @timestamp range
        # @see http://stackoverflow.com/questions/40996266/elasticsearch-5-1-unknown-key-for-a-start-object-in-filters
        # @see https://discuss.elastic.co/t/elasticsearch-watcher-error-for-range-query/70347/2
        body['query']['bool']['must'].append(self._get_timestamp_filer())

        # sample the results if needed
        if sampling is not None:
            body['query']['bool']['must'].append({
                'script': {
                    'script': {
                        'lang': 'painless',
                        'source': "Math.abs(doc['_id'].value.hashCode()) % 100 < params.sampling",
                        'params': {
                            'sampling': sampling
                        }
                    }
                }
            })

        self._logger.debug("Running {} query (limit set to {:d})".format(json.dumps(body), body.get('size', 0)))

        # use Scroll API to be able to fetch more than 10k results and prevent "search_phase_execution_exception":
        # "Result window is too large, from + size must be less than or equal to: [10000] but was [500000].
        # See the scroll api for a more efficient way to request large data sets."
        #
        # @see http://elasticsearch-py.readthedocs.io/en/master/helpers.html#scan
        rows = scan(
            client=self._es,
            clear_scroll=False,  # True causes "403 Forbidden: You don't have access to this resource"
            index=self._index,
            query=body,
            sort=["_doc"],  # return the next batch of results from every shard that still has results to return.
            size=self._batch_size,  # batch size
        )

        # get only requested amount of entries and cast them to a list
        rows = islice(rows, 0, limit)
        rows = [entry['_source'] for entry in rows]  # get data

        self._logger.info("{:d} rows returned".format(len(rows)))
        return rows