diff --git service.inc service.inc
index 62bddec..6bad89e 100644
--- service.inc
+++ service.inc
@@ -369,6 +369,8 @@ class SearchApiSolrService extends SearchApiAbstractService {
 
   public function search(SearchApiQueryInterface $query) {
     $time_method_called = microtime(TRUE);
+    // Reset request handler
+    $this->request_handler = NULL;
     // Get field information
     $index = $query->getIndex();
     $fields = $this->getFieldNames($index);
@@ -422,17 +424,20 @@ class SearchApiSolrService extends SearchApiAbstractService {
     if (!empty($facet_params['facet.field'])) {
       $params += $facet_params;
     }
+    $call_args = array(
+      'query'  => &$keys,
+      'offset' => &$offset,
+      'limit'  => &$limit,
+      'params' => &$params,
+    );
+    if ($this->request_handler) {
+      $this->setRequestHandler($this->request_handler, $call_args);
+    }
 
     try {
       // Send search request
       $time_processing_done = microtime(TRUE);
       $this->connect();
-      $call_args = array(
-        'query'  => &$keys,
-        'offset' => &$offset,
-        'limit'  => &$limit,
-        'params' => &$params,
-      );
       drupal_alter('search_api_solr_query', $call_args, $query);
       $this->preQuery($call_args, $query);
       $response = $this->solr->search($keys, $offset, $limit, $params);
@@ -540,13 +545,27 @@ class SearchApiSolrService extends SearchApiAbstractService {
    */
   protected function flattenKeys(array $keys) {
     $k = array();
+    $or = $keys['#conjunction'] == 'OR';
+    $neg = !empty($keys['#negation']);
     foreach (element_children($keys) as $i) {
       $key = $keys[$i];
       if (!$key) {
         continue;
       }
       if (is_array($key)) {
-        $k[] = $this->flattenKeys($key);
+        $subkeys = $this->flattenKeys($key);
+        if ($subkeys) {
+          $nested_expressions = TRUE;
+          // If this is a negated OR expression, we can't just use nested keys
+          // as-is, but have to put them into parantheses.
+          if ($or && $neg) {
+            if (empty($this->request_handler) || $this->request_handler == 'dismax') {
+              $this->request_handler = 'standard';
+            }
+            $subkeys = "($subkeys)";
+          }
+          $k[] = $subkeys;
+        }
       }
       else {
         $key = trim($key);
@@ -557,13 +576,39 @@ class SearchApiSolrService extends SearchApiAbstractService {
     if (!$k) {
       return '';
     }
-    if ($keys['#conjunction'] == 'OR') {
-      $k = '((' . implode(') OR (', $k) . '))';
-      return empty($keys['#negation']) ? $k : '-' . $k;
+
+    // Normally, we use the "dismax" request handler, as it yields the best
+    // results for simple queries (only single terms, phrases or simple
+    // negation). In more complex cases, we have to switch to the "standard"
+    // handler, which offers complex syntax. This is guided by the "#negation"
+    // and "#conjunction" settings. Results of the following form will be
+    // returned:
+    //
+    // #conjunction | #negation | handler  | return value
+    // ----------------------------------------------------------------
+    // AND          | FALSE     | dismax   | A B C
+    // AND          | TRUE      | standard | -(A B C)
+    // OR           | FALSE     | standard | ((A) OR (B) OR (C))
+    // OR           | TRUE      | dismax   | -A -B -C
+
+    // If there was just a single, unnested key, we can ignore all this.
+    if (count($k) == 1 && empty($nested_expressions)) {
+      $k = reset($k);
+      return $neg ? "-$k" : $k;
+    }
+
+    if ($or != $neg && (empty($this->request_handler) || $this->request_handler == 'dismax')) {
+      $this->request_handler = 'standard';
     }
 
+    if ($or) {
+      if ($neg) {
+        return '-' . implode(' -', $k);
+      }
+      return '((' . implode(') OR (', $k) . '))';
+    }
     $k = implode(' ', $k);
-    return empty($keys['#negation']) ? $k : '-(' . $k . ')';
+    return $neg ? "-($k)" : $k;
   }
 
   /**
@@ -679,6 +724,39 @@ class SearchApiSolrService extends SearchApiAbstractService {
   }
 
   /**
+   * Helper method for setting the request handler, and making necessary
+   * adjustments to the request parameters.
+   *
+   * @param $handler
+   *   Name of the handler to set.
+   * @param array $call_args
+   *   An associative array containing all four arguments to the
+   *   Apache_Solr_Service::search() call ("query", "offset", "limit" and
+   *   "params") as references.
+   *
+   * @return boolean
+   *   TRUE iff this method invocation handled the given handler. This allows
+   *   subclasses to recognize whether the request handler was already set by
+   *   this method.
+   */
+  protected function setRequestHandler($handler, array &$call_args) {
+    if ($handler == 'dismax') {
+      return TRUE;
+    }
+    if ($handler == 'standard') {
+      $keys = &$call_args['query'];
+      $params = &$call_args['params'];
+      $params['qt'] = $handler;
+      $k = $keys;
+      $fields = $params['qf'];
+      unset($params['qf']);
+      $keys = implode(":($k) OR ", array_map(array('SearchApiSolrConnection', 'escapeFieldName'), $fields)) . ":($k)";
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+  /**
    * Empty method to allow subclassed to apply custom changes before the query
    * is sent to Solr. Works exactly like hook_search_api_solr_query_alter().
    *
@@ -689,7 +767,7 @@ class SearchApiSolrService extends SearchApiAbstractService {
    * @param SearchApiQueryInterface $query
    *   The SearchApiQueryInterface object representing the executed search query.
    */
-  function preQuery(array &$call_args, SearchApiQueryInterface $query) {
+  protected function preQuery(array &$call_args, SearchApiQueryInterface $query) {
   }
 
   /**
@@ -704,7 +782,7 @@ class SearchApiSolrService extends SearchApiAbstractService {
    * @param Apache_Solr_Response $response
    *   The response object returned by Solr.
    */
-  function postQuery(array &$results, SearchApiQueryInterface $query, Apache_Solr_Response $response) {
+  protected function postQuery(array &$results, SearchApiQueryInterface $query, Apache_Solr_Response $response) {
   }
 
   //
diff --git solrconfig.xml solrconfig.xml
index 8945379..58d1d5f 100644
--- solrconfig.xml
+++ solrconfig.xml
@@ -489,14 +489,12 @@
   -->
   <requestHandler name="standard" class="solr.SearchHandler">
     <!-- default values for query parameters -->
-     <lst name="defaults">
-       <str name="echoParams">explicit</str>
-       <!--
-       <int name="rows">10</int>
-       <str name="fl">*</str>
-       <str name="version">2.1</str>
-        -->
-     </lst>
+    <lst name="defaults">
+      <str name="echoParams">none</str>
+      <str name="fl">item_id,score</str>
+      <str name="q.op">AND</str>
+      <str name="q.alt">*:*</str>
+    </lst>
   </requestHandler>
 
 <!-- Please refer to http://wiki.apache.org/solr/SolrReplication for details on configuring replication -->
@@ -524,7 +522,7 @@
   <requestHandler name="dismax" class="solr.SearchHandler" default="true">
     <lst name="defaults">
      <str name="defType">dismax</str>
-     <str name="echoParams">explicit</str>
+     <str name="echoParams">none</str>
      <float name="tie">0.01</float>
  <!--<str name="qf">
         text^0.5 features^1.0 name^1.2 sku^1.5 id^10.0 manu^1.1 cat^1.4
