public function doSearch($query = [])
    {
        if (!$this->index) {
            throw new \RuntimeException("You must set an index");
        }

        $this->prepare($query);

        // Only process query when there is a value, in order to avoid sending
        // an empty query string to ElasticSearch, its API is so weird that we
        // probably would end up with exceptions
        $value = $this->getQueryParam($query, $this->fulltextParameterName);
        if ($value) {
            $isQueryEmpty = false;

            $queryPart = [
                'query_string' => [
                    'query' => $this->fixSmartSearch((string)$value),
                    'fields' => $this->fulltextFields,
                 ],
            ];

            if ($this->fulltextAnalyzer) {
                $queryPart['query_string']['analyzer'] = $this->fulltextAnalyzer;
            }

        } else {
            $isQueryEmpty = true;
            $queryPart = [];
        }

        // This must be set before filter since filter query will be altered by
        // the applied aggregations
        $aggs = $this->buildAggQueryData($query);

        if (count($this->filterQuery)) {
            if ($isQueryEmpty) {
                $body = [
                    'query' => [
                        'constant_score' => [
                            'filter' => [
                                'fquery' => [
                                    'query' => [
                                        'query_string' => [
                                            'query' => (string)$this->filterQuery
                                        ],
                                    ],
                                    // @todo Without this ElasticSearch seems to
                                    // throw exceptions...
                                    '_cache' => true,
                                ],
                            ],
                        ],
                    ],
                ];
            } else {
                $body = [
                    'query' => [
                        'filtered' => [
                            'query'  => $queryPart,
                            'filter' => [
                                'fquery' => [
                                    'query' => [
                                        'query_string' => [
                                            'query' => (string)$this->filterQuery
                                        ],
                                    ],
                                    // @todo Without this ElasticSearch seems to
                                    // throw exceptions...
                                    '_cache' => true,
                                ],
                            ],
                        ],
                    ],
                ];
            }
        } else {
            if ($isQueryEmpty) {
                $body = [
                    'query' => [
                        'match_all' => []
                    ],
                ];
            } else {
                $body = [
                    'query' => $queryPart,
                ];
            }
        }

        if (count($this->postFilterQuery)) {
            $body['post_filter']['query_string']['query'] = (string)$this->postFilterQuery;
        }

        if ($aggs) {
            $body['aggs'] = $aggs;
        }
/*
        if ($this->fields) {
            $body['fields'] = $this->fields;
        }*/

        if (count($this->sortFields)) {
            foreach ($this->sortFields as $sort) {
                $body['sort'][] = $sort->getSortStructure();
            }
        }

        $data = [
            'index' => $this->index,
            'type'  => 'node',
            'body'  => $body,
        ];

        if (!empty($this->limit)) {
            $data['size'] = $this->limit;
            if (!empty($this->page)) {
                $data['from'] = max([0, $this->page - 1]) * $this->limit;
            }
        }

        return new Response($this, $this->client->search($data));
    }