/**
  * Searches the index for the given search term
  * @return SearchItem[]
  */
 public function Search(SearchQuery $query)
 {
     $terms = $query->GetSanitisedTerms();
     $len = count($terms);
     for ($i = 0; $i < $len; $i++) {
         $terms[$i] = Sql::ProtectString($this->connection, $terms[$i]);
         $terms[$i] = "LIKE '%" . trim($terms[$i], "'") . "%'";
     }
     $sql = "SELECT field_weight, weight_of_type, weight_within_type, weight, url, title, description, related_links_html \n                FROM\n                (\n                    SELECT SUM(field_weight) AS field_weight, weight_of_type, weight_within_type AS weight_within_type,\n                           SUM(field_weight) + weight_of_type + weight_within_type AS weight,\n                           url, title, description, related_links_html \n                    FROM\n                    (\n                        SELECT search_index_id, 500 as field_weight, weight_of_type, weight_within_type, url, title, description, related_links_html \n                        FROM nsa_search_index \n                        WHERE title " . implode(" AND title ", $terms) . " \n                        \n                        UNION\n                        \n                        SELECT search_index_id, 500 as field_weight, weight_of_type, weight_within_type, url, title, description, related_links_html \n                        FROM nsa_search_index \n                        WHERE keywords " . implode(" AND keywords ", $terms) . "  \n                        \n                        UNION\n                        \n                        SELECT search_index_id, 50 as field_weight, weight_of_type, weight_within_type, url, title, description, related_links_html \n                        FROM nsa_search_index \n                        WHERE description " . implode(" AND description ", $terms) . "  \n                        \n                        UNION\n                        \n                        SELECT search_index_id, 1 as field_weight, weight_of_type, weight_within_type, url, title, description, related_links_html \n                        FROM nsa_search_index \n                        WHERE full_text " . implode(" AND full_text ", $terms) . "  \n                    )\n                    AS unsorted_results\n                    GROUP BY search_index_id\n                    ORDER BY SUM(field_weight) DESC, SUM(weight_of_type) DESC, SUM(weight_within_type) DESC\n                ) \n                AS weighted_results\n                ORDER BY weight DESC";
     # Get the total results without paging
     $total = $this->connection->query("SELECT COUNT(*) AS total FROM ({$sql}) AS total");
     $row = $total->fetch();
     $this->total = $row->total;
     # Add paging and get the data
     if ($query->GetFirstResult() && $query->GetPageSize()) {
         $sql .= " LIMIT " . Sql::ProtectNumeric($query->GetFirstResult() - 1, false, false) . "," . Sql::ProtectNumeric($query->GetPageSize(), false, false);
     }
     $query_results = $this->connection->query($sql);
     require_once "search/search-item.class.php";
     $search_results = array();
     while ($row = $query_results->fetch()) {
         $result = new SearchItem();
         $result->Url($row->url);
         $result->Title($row->title);
         $result->Description($row->description);
         $result->RelatedLinksHtml($row->related_links_html);
         $result->WeightOfMatchedField($row->field_weight);
         $result->WeightOfType($row->weight_of_type);
         $result->WeightWithinType($row->weight_within_type);
         $result->Weight($row->weight);
         $search_results[] = $result;
     }
     return $search_results;
 }