예제 #1
4
 public function solrSearch($text)
 {
     $this->solrConnect();
     $query = new \SolrQuery();
     $query->setQuery('text: *' . $text . '*');
     $query->setStart(0);
     $query->setRows(50);
     $query_response = $this->client->query($query);
     $response = $query_response->getResponse();
     return $response->response;
 }
예제 #2
0
 public function query($q, $start = 0, $rows = 50)
 {
     $query = new SolrQuery();
     $query->setQuery($q);
     $query->setStart($start);
     $query->setRows($rows);
     $query_response = $this->client->query($query);
     $response = $query_response->getResponse();
     return $response;
 }
예제 #3
0
function getResults($userQuery)
{
    $core = 'techknowledgy_core';
    $options = array('hostname' => 'localhost', 'port' => 8983, 'timeout' => 10, 'path' => '/solr/' . $core);
    $client = new SolrClient($options);
    #if (!$client->ping()) {
    #	exit('Solr service not responding.');
    #}
    #else{
    #	print "Worked!";
    #}
    $query = new SolrQuery();
    $query->setQuery($userQuery);
    $query->setStart(0);
    $query->setRows(1000);
    $query->addField('url')->addField('title')->addField('host')->addField('content');
    $query_response = $client->query($query);
    $response = $query_response->getResponse();
    #print_r($response);
    return $response;
}
예제 #4
0
 /**
  * Simple Search interface
  *
  * @param string|array $query   The raw query string
  * @param array $params Params  can be specified like this:
  *        'offset'            - The starting offset for result documents
  *        'limit              - The maximum number of result documents to return
  *        'sort_by'           - Sort field, can be just sort field name (and asceding order will be used by default),
  *                              or can be an array of arrays like this: array('sort_field_name' => 'asc|desc')
  *                              to define sort order and sorting fields.
  *                              If sort order not asc|desc - asceding will used by default
  *        'fields'            - Fields names which are need to be retrieved from found documents
  *        'solr_params'       - Key / value pairs for other query parameters (see Solr documentation),
  *                              use arrays for parameter keys used more than once (e.g. facet.field)
  *        'locale_code'       - Locale code, it used to define what suffix is needed for text fields,
  *                              by which will be performed search request and sorting
  *        'ignore_handler'    - Flag that allows to ignore handler (qt) and make multifield search
  *
  * @return array
  */
 protected function _search($query, $params = array())
 {
     /**
      * Hard code to prevent Solr bug:
      * Bug #17009 Creating two SolrQuery objects leads to wrong query value
      * @link http://pecl.php.net/bugs/bug.php?id=17009&edit=1
      * @link http://svn.php.net/viewvc?view=revision&revision=293379
      */
     if ((int) ('1' . str_replace('.', '', solr_get_version())) < 1099) {
         $this->_connect();
     }
     $searchConditions = $this->prepareSearchConditions($query);
     if (!$searchConditions) {
         return array();
     }
     $_params = $this->_defaultQueryParams;
     if (is_array($params) && !empty($params)) {
         $_params = array_intersect_key($params, $_params) + array_diff_key($_params, $params);
     }
     $offset = isset($_params['offset']) ? (int) $_params['offset'] : 0;
     $limit = isset($_params['limit']) ? (int) $_params['limit'] : Enterprise_Search_Model_Adapter_Solr_Abstract::DEFAULT_ROWS_LIMIT;
     /**
      * Now supported search only in fulltext field
      * By default in Solr  set <defaultSearchField> is "fulltext"
      * When language fields need to be used, then perform search in appropriate field
      */
     $languageSuffix = $this->_getLanguageSuffix($params['locale_code']);
     $solrQuery = new SolrQuery();
     $solrQuery->setStart($offset)->setRows($limit);
     $solrQuery->setQuery($searchConditions);
     if (!is_array($_params['fields'])) {
         $_params['fields'] = array($_params['fields']);
     }
     if (!is_array($_params['solr_params'])) {
         $_params['solr_params'] = array($_params['solr_params']);
     }
     /**
      * Add sort fields
      */
     if ($limit > 1) {
         $sortFields = $this->_prepareSortFields($_params['sort_by']);
         foreach ($sortFields as $sortField) {
             $sortField['sortType'] = $sortField['sortType'] == 'desc' ? SolrQuery::ORDER_DESC : SolrQuery::ORDER_ASC;
             $solrQuery->addSortField($sortField['sortField'], $sortField['sortType']);
         }
     }
     /**
      * Fields to retrieve
      */
     if ($limit && !empty($_params['fields'])) {
         foreach ($_params['fields'] as $field) {
             $solrQuery->addField($field);
         }
     }
     /**
      * Now supported search only in fulltext and name fields based on dismax requestHandler (named as magento_lng).
      * Using dismax requestHandler for each language make matches in name field
      * are much more significant than matches in fulltext field.
      */
     if ($_params['ignore_handler'] !== true) {
         $_params['solr_params']['qt'] = 'magento' . $languageSuffix;
     }
     /**
      * Facets search
      */
     $useFacetSearch = isset($params['solr_params']['facet']) && $params['solr_params']['facet'] == 'on';
     if ($useFacetSearch) {
         $_params['solr_params'] += $this->_prepareFacetConditions($params['facet']);
     }
     /**
      * Suggestions search
      */
     $useSpellcheckSearch = isset($params['solr_params']['spellcheck']) && $params['solr_params']['spellcheck'] == 'true';
     if ($useSpellcheckSearch) {
         if (isset($params['solr_params']['spellcheck.count']) && (int) $params['solr_params']['spellcheck.count'] > 0) {
             $spellcheckCount = (int) $params['solr_params']['spellcheck.count'];
         } else {
             $spellcheckCount = self::DEFAULT_SPELLCHECK_COUNT;
         }
         $_params['solr_params'] += array('spellcheck.collate' => 'true', 'spellcheck.dictionary' => 'magento_spell' . $languageSuffix, 'spellcheck.extendedResults' => 'true', 'spellcheck.count' => $spellcheckCount);
     }
     /**
      * Specific Solr params
      */
     if (!empty($_params['solr_params'])) {
         foreach ($_params['solr_params'] as $name => $value) {
             if (is_array($value)) {
                 foreach ($value as $val) {
                     $solrQuery->addParam($name, $val);
                 }
             } else {
                 $solrQuery->addParam($name, $value);
             }
         }
     }
     $filtersConditions = $this->_prepareFilters($_params['filters']);
     foreach ($filtersConditions as $condition) {
         $solrQuery->addFilterQuery($condition);
     }
     $this->_client->setServlet(SolrClient::SEARCH_SERVLET_TYPE, 'select');
     /**
      * Store filtering
      */
     if ($_params['store_id'] > 0) {
         $solrQuery->addFilterQuery('store_id:' . $_params['store_id']);
     }
     if (!Mage::helper('cataloginventory')->isShowOutOfStock()) {
         $solrQuery->addFilterQuery('in_stock:true');
     }
     try {
         $this->ping();
         $response = $this->_client->query($solrQuery);
         $data = $response->getResponse();
         if (!isset($params['solr_params']['stats']) || $params['solr_params']['stats'] != 'true') {
             if ($limit > 0) {
                 $result = array('ids' => $this->_prepareQueryResponse($data));
             }
             /**
              * Extract facet search results
              */
             if ($useFacetSearch) {
                 $result['faceted_data'] = $this->_prepareFacetsQueryResponse($data);
             }
             /**
              * Extract suggestions search results
              */
             if ($useSpellcheckSearch) {
                 $resultSuggestions = $this->_prepareSuggestionsQueryResponse($data);
                 /* Calc results count for each suggestion */
                 if (isset($params['spellcheck_result_counts']) && $params['spellcheck_result_counts'] == true && count($resultSuggestions) && $spellcheckCount > 0) {
                     /* Temporary store value for main search query */
                     $tmpLastNumFound = $this->_lastNumFound;
                     unset($params['solr_params']['spellcheck']);
                     unset($params['solr_params']['spellcheck.count']);
                     unset($params['spellcheck_result_counts']);
                     $suggestions = array();
                     foreach ($resultSuggestions as $key => $item) {
                         $this->_lastNumFound = 0;
                         $this->search($item['word'], $params);
                         if ($this->_lastNumFound) {
                             $resultSuggestions[$key]['num_results'] = $this->_lastNumFound;
                             $suggestions[] = $resultSuggestions[$key];
                             $spellcheckCount--;
                         }
                         if ($spellcheckCount <= 0) {
                             break;
                         }
                     }
                     /* Return store value for main search query */
                     $this->_lastNumFound = $tmpLastNumFound;
                 } else {
                     $suggestions = array_slice($resultSuggestions, 0, $spellcheckCount);
                 }
                 $result['suggestions_data'] = $suggestions;
             }
         } else {
             $result = $this->_prepateStatsQueryResponce($data);
         }
         return $result;
     } catch (Exception $e) {
         Mage::logException($e);
     }
 }
예제 #5
0
파일: engine.php 프로젝트: janeklb/moodle
 /**
  * Get the currently indexed files for a particular document, returns the total count, and a subset of files.
  *
  * @param document $document
  * @param int      $start The row to start the results on. Zero indexed.
  * @param int      $rows The number of rows to fetch
  * @return array   A two element array, the first is the total number of availble results, the second is an array
  *                 of documents for the current request.
  */
 protected function get_indexed_files($document, $start = 0, $rows = 500)
 {
     // Build a custom query that will get any document files that are in our solr_filegroupingid.
     $query = new \SolrQuery();
     // We want to get all file records tied to a document.
     // For efficiency, we are building our own, stripped down, query.
     $query->setQuery('*');
     $query->setRows($rows);
     $query->setStart($start);
     // We want a consistent sorting.
     $query->addSortField('id');
     // We only want the bare minimum of fields.
     $query->addField('id');
     $query->addField('modified');
     $query->addField('title');
     $query->addField('solr_fileid');
     $query->addField('solr_filecontenthash');
     $query->addField('solr_fileindexstatus');
     $query->addFilterQuery('{!cache=false}solr_filegroupingid:(' . $document->get('id') . ')');
     $query->addFilterQuery('type:' . \core_search\manager::TYPE_FILE);
     $response = $this->get_query_response($query);
     if (empty($response->response->numFound)) {
         return array(0, array());
     }
     return array($response->response->numFound, $this->convert_file_results($response));
 }
<?php

include "bootstrap.php";
$options = array('hostname' => SOLR_SERVER_HOSTNAME, 'login' => SOLR_SERVER_USERNAME, 'password' => SOLR_SERVER_PASSWORD, 'port' => SOLR_SERVER_PORT, 'path' => SOLR_SERVER_PATH);
$client = new SolrClient($options);
$query = new SolrQuery();
$query->setQuery('manu:"Apple Computer Inc." OR text:apple');
$query->setStart(0);
$query->setRows(50);
$query->addField('cat')->addField('features')->addField('id')->addField('timestamp');
$query_response = $client->query($query);
$response = $query_response->getResponse();
print_r($response);
 /**
  * Run the search against a sanitized query string via Solr.
  *
  * @param string $string
  * @param array $scriptProperties The scriptProperties array from the SimpleSearch snippet
  * @return array
  */
 public function search($string, array $scriptProperties = array())
 {
     /** @var SolrQuery $query */
     $query = new SolrQuery();
     $query->setQuery($string);
     /* set limit */
     $perPage = $this->modx->getOption('perPage', $scriptProperties, 10);
     if (!empty($perPage)) {
         $offset = $this->modx->getOption('start', $scriptProperties, 0);
         $offsetIndex = $this->modx->getOption('offsetIndex', $scriptProperties, 'sisea_offset');
         if (isset($_REQUEST[$offsetIndex])) {
             $offset = (int) $_REQUEST[$offsetIndex];
         }
         $query->setStart($offset);
         $query->setRows($perPage);
     }
     /* add fields to search */
     $fields = $this->modx->getFields('modResource');
     foreach ($fields as $fieldName => $default) {
         $query->addField($fieldName);
     }
     $includeTVs = $this->modx->getOption('includeTVs', $scriptProperties, false);
     $includeTVList = $this->modx->getOption('includeTVList', $scriptProperties, '');
     if ($includeTVs) {
         $sql = $this->modx->newQuery('modTemplateVar');
         $sql->select($this->modx->getSelectColumns('modTemplateVar', '', '', array('id', 'name')));
         if (!empty($includeTVList)) {
             $includeTVList = explode(',', $includeTVList);
             $includeTVList = array_map('trim', $includeTVList);
             $sql->where(array('name:IN' => $includeTVList));
         }
         $sql->sortby($this->modx->escape('name'), 'ASC');
         $sql->prepare();
         $sql = $sql->toSql();
         $tvs = $this->modx->query($sql);
         if ($tvs && $tvs instanceof PDOStatement) {
             while ($tv = $tvs->fetch(PDO::FETCH_ASSOC)) {
                 $query->addField($tv['name']);
             }
         }
     }
     /* handle hidemenu option */
     $hideMenu = $this->modx->getOption('hideMenu', $scriptProperties, 2);
     if ($hideMenu != 2) {
         $query->addFilterQuery('hidemenu:' . ($hideMenu ? 1 : 0));
     }
     /* handle contexts */
     $contexts = $this->modx->getOption('contexts', $scriptProperties, '');
     $contexts = !empty($contexts) ? $contexts : $this->modx->context->get('key');
     $contexts = implode(' ', explode(',', $contexts));
     $query->addFilterQuery('context_key:(' . $contexts . ')');
     /* handle restrict search to these IDs */
     $ids = $this->modx->getOption('ids', $scriptProperties, '');
     if (!empty($ids)) {
         $idType = $this->modx->getOption('idType', $this->config, 'parents');
         $depth = $this->modx->getOption('depth', $this->config, 10);
         $ids = $this->processIds($ids, $idType, $depth);
         $query->addFilterQuery('id:(' . implode(' ', $ids) . ')');
     }
     /* handle exclude IDs from search */
     $exclude = $this->modx->getOption('exclude', $scriptProperties, '');
     if (!empty($exclude)) {
         $exclude = $this->cleanIds($exclude);
         $exclude = implode(' ', explode(',', $exclude));
         $query->addFilterQuery('-id:(' . $exclude . ')');
     }
     /* basic always-on conditions */
     $query->addFilterQuery('published:1');
     $query->addFilterQuery('searchable:1');
     $query->addFilterQuery('deleted:0');
     /* sorting */
     if (!empty($scriptProperties['sortBy'])) {
         $sortDir = $this->modx->getOption('sortDir', $scriptProperties, 'desc');
         $sortDirs = explode(',', $sortDir);
         $sortBys = explode(',', $scriptProperties['sortBy']);
         $dir = 'desc';
         for ($i = 0; $i < count($sortBys); $i++) {
             if (isset($sortDirs[$i])) {
                 $dir = $sortDirs[$i];
             }
             $dir = strtolower($dir) == 'asc' ? SolrQuery::ORDER_ASC : SolrQuery::ORDER_DESC;
             $query->addSortField($sortBys[$i], $dir);
         }
     }
     /* prepare response array */
     $response = array('total' => 0, 'start' => !empty($offset) ? $offset : 0, 'limit' => $perPage, 'status' => 0, 'query_time' => 0, 'results' => array());
     /* query Solr */
     try {
         $queryResponse = $this->client->query($query);
         $responseObject = $queryResponse->getResponse();
         if ($responseObject) {
             $response['total'] = $responseObject->response->numFound;
             $response['query_time'] = $responseObject->responseHeader->QTime;
             $response['status'] = $responseObject->responseHeader->status;
             $response['results'] = array();
             if (!empty($responseObject->response->docs)) {
                 foreach ($responseObject->response->docs as $doc) {
                     $d = array();
                     foreach ($doc as $k => $v) {
                         $d[$k] = $v;
                     }
                     /** @var modResource $resource */
                     $resource = $this->modx->newObject($d['class_key']);
                     if ($resource->checkPolicy('list')) {
                         $response['results'][] = $d;
                     }
                 }
             }
         }
     } catch (Exception $e) {
         $this->modx->log(xPDO::LOG_LEVEL_ERROR, 'Error running query on Solr server: ' . $e->getMessage());
     }
     return $response;
 }
예제 #8
0
 /**
  *  Tests {@link SolrQuery::setStart()} with invalid parameters.
  * 
  * @expectedException InvalidArgumentException
  * @dataProvider      provideInvalidOffsets
  */
 function testInvalidOffsets($param)
 {
     $query = new SolrQuery($this->solrQuery);
     $query->setStart($param);
 }
예제 #9
0
파일: Accessor.php 프로젝트: uedcw/webstory
 private function find_response()
 {
     if (!isset($this->query)) {
         throw new SolrException('SolrAccessor Exception: query undefined', '7700');
     }
     $query = new SolrQuery();
     $query->setQuery($this->query);
     $query->addField($this->mapping['key']);
     if (is_array($this->fields)) {
         foreach ($this->fields as $field) {
             $query->addField($field);
         }
     }
     if (is_array($this->filters)) {
         foreach ($this->filters as $field => $value) {
             $query->addFilterQuery("{$field}:{$value}");
         }
     }
     if (is_array($this->sorts)) {
         foreach ($this->sorts as $field => $type) {
             $query->addSortField($field, $type);
         }
     }
     if (is_array($this->query_field) && !empty($this->query_field)) {
         $arrQueryFields = array();
         foreach ($this->query_field as $field => $boost) {
             $arrQueryFields[] = $field . '^' . $boost;
         }
         $query->setParam('qf', implode(' ', $arrQueryFields));
         $query->setParam('qt', 'dismax');
     }
     if (isset($this->start)) {
         $query->setStart($this->start);
     }
     if (isset($this->rows)) {
         $query->setRows($this->rows);
     }
     if (is_array($this->facets)) {
         $query->setFacet(true);
         $query->setFacetMinCount($this->facet_min_count);
         foreach ($this->facets as $facet) {
             $query->addFacetField($facet['filed']);
             if (isset($facet['limit'])) {
                 $limit = intval($facet['limit']);
                 $query->setFacetLimit($limit);
             }
             if (isset($facet['sort'])) {
                 $sort = $facet['sort'] == 'index' ? $query::FACET_SORT_INDEX : $query::FACET_SORT_COUNT;
                 $query->setFacetSort($sort, $facet['filed']);
             }
         }
     }
     if (!empty($this->facet_query_array) && is_array($this->facet_query_array)) {
         $query->setFacet(true);
         $query->setFacetMinCount($this->facet_min_count);
         foreach ($this->facet_query_array as $valFacetQuery) {
             $query->addFacetQuery($valFacetQuery);
         }
     }
     $client = MPF_Solr_Factory::get_instance()->get_client($this->mapping['instance']);
     $response = $client->query($query);
     $debug = explode("\n", $client->getDebug());
     //TODO use getRawRequest instead of debug
     $raw_request = @$debug[13];
     if (substr($raw_request, 0, 2) != 'q=') {
         $raw_request = @$debug[12];
     }
     MPF::get_instance()->debug(__CLASS__ . '::' . __FUNCTION__ . ':' . @$response->getRequestUrl() . '&' . $raw_request);
     return $response->getResponse();
 }
예제 #10
0
 /**
  * Run the search based on the specified search string.
  *
  * @param string $string The string to run the search on.
  * @param int $limit The number of results to limit to.
  * @param int $start The starting result index to search from.
  * @param array $conditions An array of conditions to add to the search filter.
  * @return array An array of search results.
  */
 public function run($string, $limit = 10, $start = 0, array $conditions = array())
 {
     /* sanitize string */
     $string = str_replace(array('!'), '', $string);
     /* @var SolrQuery $query */
     $query = new SolrQuery();
     $query->setQuery($string);
     $query->setStart($start);
     $query->setRows($limit);
     // turn board array into solr-compatible OR argument
     if (isset($conditions['board']) && is_array($conditions['board'])) {
         $c = array();
         foreach ($conditions['board'] as $board) {
             $c[] = $board['id'];
         }
         $conditions['board'] = '(' . implode(' OR ', $c) . ')';
     }
     // @todo rectify this workaround
     // convert author (id) lookup to username (name) lookup
     if (isset($conditions['author']) && isset($_REQUEST['user'])) {
         unset($conditions['author']);
         $conditions['username'] = trim($_REQUEST['user']);
     }
     // allow for non-default Solr requestHandler
     if (isset($this->_searchOptions['requestHandler']) && !empty($this->_searchOptions['requestHandler'])) {
         $this->client->setServlet(SolrClient::SEARCH_SERVLET_TYPE, $this->_searchOptions['requestHandler']);
     } else {
         $query->addField('id')->addField('title')->addField('message')->addField('thread')->addField('board')->addField('category')->addField('author')->addField('username')->addField('replies')->addField('createdon')->addField('board_name')->addField('url')->addField('private');
     }
     foreach ($conditions as $k => $v) {
         $query->addFilterQuery($k . ':' . $v);
     }
     $response = array('total' => 0, 'start' => $start, 'limit' => $limit, 'status' => 0, 'query_time' => 0, 'results' => array());
     try {
         $queryResponse = $this->client->query($query);
         $responseObject = $queryResponse->getResponse();
         if ($responseObject) {
             $response['total'] = $responseObject->response->numFound;
             $response['query_time'] = $responseObject->responseHeader->QTime;
             $response['status'] = $responseObject->responseHeader->status;
             $response['results'] = array();
             if (!empty($responseObject->response->docs)) {
                 foreach ($responseObject->response->docs as $doc) {
                     $d = array();
                     foreach ($doc as $k => $v) {
                         if ($k == 'createdon') {
                             $v = strftime($this->discuss->dateFormat, strtotime($v));
                         }
                         $d[$k] = $v;
                     }
                     $response['results'][] = $d;
                 }
             }
         }
     } catch (Exception $e) {
         $this->modx->log(xPDO::LOG_LEVEL_ERROR, 'Error running query on Solr server: ' . $e->getMessage());
     }
     return $response;
 }
예제 #11
0
 function query($args, $document)
 {
     $this->validate($args);
     $xml = new xml();
     $solr = $this->datasource->get($this->core);
     switch ($this->method) {
         case 'add':
             !empty($args) or runtime_error('Solr add method should accept parameters');
             if (is_array(reset($args))) {
                 $docs = array();
                 foreach (reset($args) as $document) {
                     $doc = new SolrInputDocument();
                     foreach ($document as $name => $value) {
                         if (is_array($value)) {
                             foreach ($value as $element) {
                                 $doc->addField($name, $element);
                             }
                         } else {
                             $doc->addField($name, $value);
                         }
                     }
                     $docs[] = $doc;
                 }
                 $solr->addDocuments($docs);
             } else {
                 $doc = new SolrInputDocument();
                 foreach ($args as $name => $value) {
                     $doc->addField($name, $value);
                 }
                 $solr->addDocument($doc);
             }
             $solr->request("<commit/>");
             break;
         case 'delete':
             $solr->deleteByQuery(vars::apply_assoc($this->body, $args));
             $solr->request("<commit/>");
             break;
         case 'query':
             $root = $xml->element($this->root[0]);
             $xml->append($root);
             $query = new SolrQuery(vars::apply_assoc($this->body, $args));
             foreach ($this->order_by as $name => $order) {
                 $query->addSortField($name, $order == 'desc' ? SolrQuery::ORDER_DESC : SolrQuery::ORDER_ASC);
             }
             if (!is_null($this->offset)) {
                 $query->setStart(vars::apply_assoc($this->offset, $args));
             }
             is_null($this->count) or $query->setRows(vars::apply_assoc($this->count, $args));
             $response = $solr->query($query);
             $object = $response->getResponse();
             if (is_array($object['response']['docs'])) {
                 $root['@matched'] = $object['response']['numFound'];
                 foreach ($object['response']['docs'] as $doc) {
                     $item = $xml->element($this->item[0]);
                     $root->append($item);
                     foreach ($doc as $name => $value) {
                         if (is_array($value)) {
                             $array = $xml->element($name);
                             $item->append($array);
                             foreach ($value as $element) {
                                 $element = $xml->element('element', $element);
                                 $array->append($element);
                             }
                         } else {
                             $node = $this->transform($xml, $name, $value);
                             $item->append($node);
                         }
                     }
                 }
             } else {
                 $this->empty or runtime_error('Procedure returned an empty result: ' . $this->mangled());
             }
             break;
         default:
             runtime_error('Unknown Solr method: ' . $this->method);
     }
     return $xml;
 }
<?php

$query = new SolrQuery();
$query->setParam('a', 1);
$query->setParam('b', 2);
$query->setParam('c', 3);
$query->setStart(4)->setQuery('solr')->setTimeAllowed(500)->setRows(17);
$query->addField('israel')->addField('joshua')->addField('june');
$query->addSortField('cat', 0);
$query->addFilterQuery('solr')->addFilterQuery('solr1')->addFilterQuery('solr2');
echo $query;
echo "\n";
예제 #13
0
 function query_direct($args)
 {
     $solr = $this->solr->get($this->core);
     switch ($this->method) {
         case 'add':
             isset($args['_documents']) or backend_error('bad_query', 'Solr _documents argument missing');
             $docs = [];
             foreach ($args['_documents'] as $name => $value) {
                 if (is_array($value)) {
                     if ($value === array_values($value)) {
                         foreach ($value as $document) {
                             $docs[] = self::add($document);
                         }
                     } else {
                         $docs[] = self::add($value);
                     }
                 } else {
                     if (is_object($value)) {
                         $docs[] = self::add(get_object_vars($value));
                     } else {
                         backend_error('bad_args', 'Bad Solr document: ' . $name);
                     }
                 }
             }
             $solr->addDocuments($docs);
             $solr->request("<commit/>");
             break;
         case 'delete':
             $solr->deleteByQuery(self::substitute($this->body, $args));
             $solr->request("<commit/>");
             break;
         case 'query':
             $query = new SolrQuery(self::substitute($this->body, $args));
             foreach ($this->order_by as $name => $mode) {
                 if ($mode->type == 'normal') {
                     $query->addSortField($name, $mode->order == 'desc' ? SolrQuery::ORDER_DESC : SolrQuery::ORDER_ASC);
                 } elseif ($mode->type == 'spatial') {
                     $query->setParam('spatial', true);
                     $query->setParam('sfield', $name);
                     if (isset($mode->point)) {
                         $query->setParam('pt', $args[$mode->point]);
                     }
                     $query->setParam('sort', self::substitute($mode->order, $args));
                 }
             }
             $offset = isset($args['_offset']) ? $args['_offset'] : $this->offset;
             $count = isset($args['_count']) ? $args['_count'] : $this->count;
             is_null($offset) or $query->setStart($offset);
             is_null($count) or $query->setRows($count);
             if (isset($args['_fields']) or isset($args['_queries'])) {
                 $query->setFacet(true);
                 if (isset($args['_fields'])) {
                     foreach ($args['_fields'] as $field) {
                         $query->addFacetField($field);
                     }
                 }
                 if (isset($args['_queries'])) {
                     foreach ($args['_queries'] as $fq) {
                         $query->addFacetQuery($fq);
                     }
                 }
             }
             $result = new stdClass();
             $result->matched = 0;
             $result->documents = [];
             $result->fields = new stdClass();
             $result->queries = new stdClass();
             $response = $solr->query($query);
             $object = $response->getResponse();
             if (is_array($object['response']['docs'])) {
                 $result->matched = $object['response']['numFound'];
                 foreach ($object['response']['docs'] as $doc) {
                     $document = new stdClass();
                     foreach ($doc as $name => $value) {
                         if ($name != '_version_') {
                             if (is_array($value)) {
                                 $items = [];
                                 foreach ($value as $item) {
                                     $items[] = $item;
                                 }
                                 $document->{$name} = $items;
                             } else {
                                 $document->{$name} = $value;
                             }
                         }
                     }
                     $result->documents[] = $document;
                 }
             } else {
                 !$this->required or backend_error('bad_input', 'Empty response from Solr procedure');
             }
             if (isset($args['_fields'])) {
                 foreach ($object['facet_counts']['facet_fields'] as $name => $counts) {
                     $array = [];
                     foreach ($counts as $value => $count) {
                         $array[$value] = $count;
                     }
                     $result->fields->{$name} = (object) $array;
                 }
             }
             if (isset($args['_queries'])) {
                 foreach ($object['facet_counts']['facet_queries'] as $fq => $count) {
                     $result->queries->{$fq} = $count;
                 }
             }
             switch ($this->result) {
                 case 'array':
                     return empty($result) ? (object) ['matched' => 0, 'documents' => [], 'fields' => (object) null, 'queries' => (object) null] : $result;
                 case 'object':
                     if ($result->matched == 1 and count($result->documents) == 1) {
                         return $result->documents[0];
                     } elseif ($result->matched == 0 and count($result->documents) == 0) {
                         return null;
                     } else {
                         backend_error('bad_query', 'Solr query result is not an object');
                     }
                 default:
                     backend_error('bad_query', 'Unsupported Solr query result type: ' . $this->result);
             }
     }
 }