You are here

class elasticsearch_connector_views_query in Elasticsearch Connector 7.5

Same name and namespace in other branches
  1. 7 modules/elasticsearch_connector_views/elasticsearch_connector_views_query.inc \elasticsearch_connector_views_query
  2. 7.2 modules/elasticsearch_connector_views/elasticsearch_connector_views_query.inc \elasticsearch_connector_views_query

@file Class for handling a view that gets its data not from the database, but from a Solr server.

Hierarchy

Expanded class hierarchy of elasticsearch_connector_views_query

2 string references to 'elasticsearch_connector_views_query'
elasticsearch_connector_views_views_data in modules/elasticsearch_connector_views/elasticsearch_connector_views.views.inc
Implementation of hook_views_data().
elasticsearch_connector_views_views_plugins in modules/elasticsearch_connector_views/elasticsearch_connector_views.views.inc
Implementation of hook_views_plugins().

File

modules/elasticsearch_connector_views/elasticsearch_connector_views_query.inc, line 7
Class for handling a view that gets its data not from the database, but from a Solr server.

View source
class elasticsearch_connector_views_query extends views_plugin_query {

  /**
   * Array of parameters for Solr query.
   */
  protected $params;
  protected $query_params;

  /**
   * Array of all encountered errors. Each of these is fatal, meaning that a
   * non-empty $errors property will result in an empty result being returned.
   *
   * @var array
   */
  protected $errors;

  /**
   * Array of where conditions.
   *
   * Neede for grouppin of query conditions.
   */
  protected $where = array();

  /**
   * Array holding sort fields and their order (ASC or DESC), to avoid duplication
   */
  protected $sort_fields = array();
  public function build(&$view) {
    $view
      ->init_pager();

    // Let the pager modify the query to add limits.
    $this->pager
      ->query();

    // Set aliases of the fields.
    foreach ($view->field as $field_name => &$field) {
      $field->field_alias = $field_name;
      $field->aliases['entity_type'] = 'entity_type';
    }

    // Add fields to the query so they will be shown in solr document.
    $this->params['fields'] = array_keys($view->field);
    $this->params['fields'][] = '_source';
    $params = array();
    if (isset($this->params['q']) && !empty($this->params['q'])) {

      // If we have more than one field we make a multi match query
      if (count($this->params['fields']) > 1) {
        $params['query']['multi_match'] = array(
          'query' => $this->params['q'],
          'fields' => array_values($this->params['fulltext_fields']),
        );
      }
      else {
        $params['query']['match'] = array(
          reset($this->params['fulltext_fields']) => array(
            'query' => $this->params['q'],
            'operator' => $this->params['fulltext_operator'],
          ),
        );
      }
    }
    $params['size'] = $this->pager->options['items_per_page'];
    $params['from'] = $this->pager->current_page * $this->pager->options['items_per_page'];

    // If we display all items without pager remove the size limit to return
    // all documents from elasticsearch.
    if ($params['size'] == 0) {
      unset($params['size']);
    }

    // Add fields.
    // We are specifying which fields to be visible!
    $params['fields'] = array();
    if (isset($this->params['fields'])) {
      $params['fields'] = array_merge($params['fields'], $this->params['fields']);
    }
    $where = $this->where;
    $params['filter'] = $this
      ->build_filter_array($where);

    // Elastic complains when there is an empty filter array
    if (empty($params['filter'])) {
      unset($params['filter']);
    }

    // if a filter and query is set, combine them into a filtered query
    if (isset($params['filter']) && isset($params['query'])) {
      $temp = $params['query'];
      unset($params['query']);
      $params['query']['filtered'] = array(
        'query' => $temp,
        'filter' => $params['filter'],
      );
      unset($params['filter']);
    }

    // Add sorting.
    if (!empty($this->sort_fields)) {
      $params['sort'] = $this
        ->build_sort_array();
    }
    $this->query_params = $params;

    // Export parameters for preview.
    $view->build_info['query'] = var_export($params, TRUE);
  }

  /**
   * Let modules modify the query just prior to finalizing it.
   */
  function alter(&$view) {
    foreach (module_implements('views_query_alter') as $module) {
      $function = $module . '_views_query_alter';
      $function($view, $this);
    }
  }

  /**
   * Executes the query and fills the associated view object with according
   * values.
   *
   * Values to set: $view->result, $view->total_rows, $view->execute_time,
   * $view->pager['current_page'].
   */
  public function execute(&$view) {
    $view->result = array();
    $view->total_rows = 0;
    $view->execute_time = 0;
    $base_table_parts = explode('__', $view->base_table);
    $cluster_id = $base_table_parts[1];
    $index = $base_table_parts[2];
    $type = $base_table_parts[3];
    try {
      $start = microtime(TRUE);
      $client = elasticsearch_connector_get_client_by_id($cluster_id);
      if ($client) {
        $view->execute_time = microtime(TRUE) - $start;

        // Execute the search.
      }

      // Execute search.
      $response = $client
        ->search(array(
        'index' => $index,
        'type' => $type,
        'body' => $this->query_params,
      ))
        ->getRawResponse();

      // Store results.
      if (!empty($response['hits']['hits'])) {
        foreach ($response['hits']['hits'] as $doc) {
          $result_doc = array();
          foreach ($doc['fields'] as $field_name => $field_value) {

            // Handle multivalue with concatenation for now.
            $result_doc[$field_name] = implode(' | ', $field_value);
          }
          $result_doc['_source'] = $doc['_source'];
          $view->result[] = (object) $result_doc;
        }
      }

      // Store response into the object.
      $this->response = $response;

      // Store the results.
      $this->pager->total_items = $view->total_rows = $response['hits']['total'];
      $this->pager
        ->update_page_info();

      // We shouldn't use $results['performance']['complete'] here, since
      // extracting the results probably takes considerable time as well.
      $view->execute_time = $response['took'];
    } catch (Exception $e) {
      $this->errors[] = $e
        ->getMessage();
    }
    if ($this->errors) {
      foreach ($this->errors as $msg) {
        drupal_set_message(check_plain($msg), 'error');
      }
      $view->result = array();
      $view->total_rows = 0;
      $view->execute_time = 0;
      return;
    }
  }
  public function add_filter($type, $value, $exclude = FALSE) {
    $exclude_string = $exclude ? '-' : '';
    $this->params['filters'][] = $exclude_string . $type . ':(' . $value . ')';
  }
  public function add_filter_string($string) {

    // TODO: Rework if necessary.
    $this->params['q.alt'][] = $string;
  }
  public function add_sort($field, $order) {
    if (!isset($this->sort_fields[$field]) || $this->sort_fields[$field] != drupal_strtolower($order)) {
      $this->sort_fields[$field] = drupal_strtolower($order);
    }
  }
  public function build_sort_array() {
    $sort = array();
    foreach ($this->sort_fields as $field => $order) {
      $sort[] = array(
        $field => $order,
      );
    }
    return $sort;
  }
  public function add_parameter($key, $value) {
    $this->params[$key] = $value;
  }
  public function add_field($table_alias, $field, $alias = '', $params = array()) {
    if (isset($table_alias[$field])) {
      return $table_alias[$field];
    }
  }
  public function get_params() {
    return $this->params;
  }
  function build_filter_array($where) {
    $filter = array();
    foreach ($where as $wh) {
      foreach ($wh['conditions'] as $cond) {
        $filter[drupal_strtolower($wh['type'])][] = $cond['field'];
      }
    }
    if (count($filter) > 1) {
      $filter = array(
        drupal_strtolower($this->group_operator) => $filter,
      );
    }
    return $filter;
  }

  /**
   * Support for groupping.
   *
   * @see views_plugin_query_default::add_where().
   */
  function add_where($group, $field, $value = NULL, $operator = NULL) {

    // Ensure all variants of 0 are actually 0. Thus '', 0 and NULL are all
    // the default group.
    if (empty($group)) {
      $group = 0;
    }

    // Check for a group.
    if (!isset($this->where[$group])) {
      $this
        ->set_where_group('AND', $group);
    }
    $this->where[$group]['conditions'][] = array(
      'field' => $field,
      'value' => $value,
      'operator' => $operator,
    );
  }

  /**
   * Support for groupping.
   *
   * @see views_plugin_query_default::set_where_group().
   */
  function set_where_group($type = 'AND', $group = NULL, $where = 'where') {

    // Set an alias.
    $groups =& $this->{$where};
    if (!isset($group)) {
      $group = empty($groups) ? 1 : max(array_keys($groups)) + 1;
    }

    // Create an empty group
    if (empty($groups[$group])) {
      $groups[$group] = array(
        'conditions' => array(),
        'args' => array(),
      );
    }
    $groups[$group]['type'] = strtoupper($type);
    return $group;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
elasticsearch_connector_views_query::$errors protected property Array of all encountered errors. Each of these is fatal, meaning that a non-empty $errors property will result in an empty result being returned.
elasticsearch_connector_views_query::$params protected property Array of parameters for Solr query.
elasticsearch_connector_views_query::$query_params protected property
elasticsearch_connector_views_query::$sort_fields protected property Array holding sort fields and their order (ASC or DESC), to avoid duplication
elasticsearch_connector_views_query::$where protected property Array of where conditions.
elasticsearch_connector_views_query::add_field public function
elasticsearch_connector_views_query::add_filter public function
elasticsearch_connector_views_query::add_filter_string public function
elasticsearch_connector_views_query::add_parameter public function
elasticsearch_connector_views_query::add_sort public function
elasticsearch_connector_views_query::add_where function Support for groupping.
elasticsearch_connector_views_query::alter function Let modules modify the query just prior to finalizing it. Overrides views_plugin_query::alter
elasticsearch_connector_views_query::build public function Builds the necessary info to execute the query. Overrides views_plugin_query::build
elasticsearch_connector_views_query::build_filter_array function
elasticsearch_connector_views_query::build_sort_array public function
elasticsearch_connector_views_query::execute public function Executes the query and fills the associated view object with according values. Overrides views_plugin_query::execute
elasticsearch_connector_views_query::get_params public function
elasticsearch_connector_views_query::set_where_group function Support for groupping. Overrides views_plugin_query::set_where_group
views_object::$definition public property Handler's definition.
views_object::$options public property Except for displays, options for the object will be held here. 1
views_object::altered_option_definition function Collect this handler's option definition and alter them, ready for use.
views_object::construct public function Views handlers use a special construct function. 4
views_object::destroy public function Destructor. 2
views_object::export_option public function 1
views_object::export_options public function
views_object::export_option_always public function Always exports the option, regardless of the default value.
views_object::options Deprecated public function Set default options on this object. 1
views_object::option_definition public function Information about options for all kinds of purposes will be held here. 13
views_object::set_default_options public function Set default options.
views_object::set_definition public function Let the handler know what its full definition is.
views_object::unpack_options public function Unpack options over our existing defaults, drilling down into arrays so that defaults don't get totally blown away.
views_object::unpack_translatable public function Unpack a single option definition.
views_object::unpack_translatables public function Unpacks each handler to store translatable texts.
views_object::_set_option_defaults public function
views_plugin::$display public property The current used views display.
views_plugin::$plugin_name public property The plugin name of this plugin, for example table or full.
views_plugin::$plugin_type public property The plugin type of this plugin, for example style or query.
views_plugin::$view public property The top object of a view. Overrides views_object::$view 1
views_plugin::additional_theme_functions public function Provide a list of additional theme functions for the theme info page.
views_plugin::plugin_title public function Return the human readable name of the display.
views_plugin::theme_functions public function Provide a full list of possible theme templates used by this style.
views_plugin::validate public function Validate that the plugin is correct and can be saved. 3
views_plugin_query::$pager public property A pager plugin that should be provided by the display. 1
views_plugin_query::add_signature public function Add a signature to the query, if such a thing is feasible. 1
views_plugin_query::get_aggregation_info public function Get aggregation info for group by queries. 1
views_plugin_query::get_result_entities public function Returns the according entity objects for the given query results. 1
views_plugin_query::init public function Constructor; Create the basic query object and fill with default values. 1
views_plugin_query::options_form public function Add settings for the ui. Overrides views_plugin::options_form 1
views_plugin_query::options_submit public function Handle any special handling on the validate form. Overrides views_plugin::options_submit 1
views_plugin_query::options_validate public function Validate the options form. Overrides views_plugin::options_validate
views_plugin_query::query public function Generate a query and a countquery from all of the information supplied to the object. Overrides views_plugin::query 1
views_plugin_query::render_pager public function Render the pager, if necessary.
views_plugin_query::set_group_operator public function Control how all WHERE and HAVING groups are put together.
views_plugin_query::set_limit public function Set a LIMIT on the query, specifying a maximum number of results.
views_plugin_query::set_offset public function Set an OFFSET on the query, specifying a number of results to skip
views_plugin_query::summary_title public function Returns the summary of the settings in the display. Overrides views_plugin::summary_title