diff --git a/service.inc b/service.inc
index cba9a03..420e7ca 100644
--- a/service.inc
+++ b/service.inc
@@ -542,39 +542,102 @@ class SearchApiSolrService extends SearchApiAbstractService {
   /**
    * Flatten a keys array into a single search string.
    *
+   * Our default query handler, "dismax", does not understand any special syntax
+   * beyond grouping terms as phrases (""), and making terms/phrases mandatory
+   * (+) or prohibited (-). Dismax also does not support nested queries.
+   *
+   * Since dismax does not support nested queries, the closest #conjuction or
+   * #negation value will be used. Using this method, a $keys array like:
+   *
+   *   array(
+   *     '#conjunction' => 'AND',
+   *     'yellow',
+   *     array(
+   *       '#conjunction' => 'OR',
+   *       'blue',
+   *       'purple',
+   *     ),
+   *     array(
+   *       '#negation' => TRUE,
+   *       'smurf',
+   *     )
+   *   )
+   *
+   * Would result in the query string:
+   *
+   *   +"yellow" "blue" "purple" -"smurf"
+   *
+   * @see http://wiki.apache.org/solr/DisMaxQParserPlugin#Query_Syntax
+   *
+   * If the 'q' parameter is left blank, and a query is placed in the 'q.alt'
+   * parameter, the "standard" query parser will be used. This query parser
+   * supports AND, OR, negation, field qualifiers, nested logic, ranges,
+   * wildcards, etc. This implementation of ::flattenKeys() does not build
+   * queries with syntax for the "standard" query parser.
+   *
    * @param array $keys
    *   The keys array to flatten, formatted as specified by
    *   SearchApiQueryInterface::getKeys().
    *
    * @return string
    *   A Solr query string representing the same keys.
+   *
+   * @see SearchApiSolrService::_applyConjunctions()
    */
   protected function flattenKeys(array $keys) {
+    // Extract search terms. Note that this only does one level of flattening.
     $k = array();
     foreach (element_children($keys) as $i) {
       $key = $keys[$i];
-      if (!$key) {
-        continue;
-      }
       if (is_array($key)) {
-        $k[] = $this->flattenKeys($key);
+        // Flatten this key. There is no nested logic, but the nearest
+        // #conjunction or #negation will apply to each individual term.
+        $flattened = $this->flattenKeys($key);
+        $k = array_merge($k, $flattened);
       }
-      else {
+      elseif ($key) {
+        // Escape the key, and apply conjunction/negation from the main $keys
+        // array.
         $key = trim($key);
-        $key = SearchApiSolrConnection::phrase($key);
-        $k[] = $key;
+        $flattened = SearchApiSolrConnection::phrase($key);
+        $k[] = $this->_applyConjunctions($keys, $flattened);
       }
     }
-    if (!$k) {
+
+    // Conjuction and negation is already applied to each term.
+    return implode(' ', $k);
+  }
+
+  /**
+   * Apply conjunctions or negation to terms when building a search string.
+   *
+   * @param array $keys
+   *   The original keys array, which optionally contains #conjunction or
+   *   #negation keys.
+   * @param string $term
+   *   An escaped search term.
+   *
+   * @return string
+   *   A search string with conjunction or negation from $keys applied.
+   *
+   * @see SearchApiSolrService::flattenKeys()
+   */
+  protected function _applyConjunctions(array $keys, $term) {
+    // Don't apply conjunction, negation, etc. to empty queries.
+    if (!$term) {
       return '';
     }
-    if ($keys['#conjunction'] == 'OR') {
-      $k = '((' . implode(') OR (', $k) . '))';
-      return empty($keys['#negation']) ? $k : '-' . $k;
+
+    // Apply AND conjunctions...
+    if (!empty($keys['#conjunction']) && $keys['#conjunction'] == 'AND') {
+      $term = '+' . $term;
+    }
+    // ... or apply negation.
+    elseif (!empty($keys['#negation'])) {
+      $term = '-' . $term;
     }
 
-    $k = implode(' ', $k);
-    return empty($keys['#negation']) ? $k : '-(' . $k . ')';
+    return $term;
   }
 
   /**
