|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* @author Carsten Brandt <mail@cebe.cc>
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace yii\elasticsearch;
|
|
|
|
|
|
|
|
|
|
|
|
use yii\base\Component;
|
|
|
|
use yii\helpers\Json;
|
|
|
|
|
|
|
|
// camelCase vs. _
|
|
|
|
// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/common-options.html#_result_casing
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class Command
|
|
|
|
*
|
|
|
|
* http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/glossary.html
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
class Command extends Component
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var Connection
|
|
|
|
*/
|
|
|
|
public $db;
|
|
|
|
|
|
|
|
public $api = '_search';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string|array the indexes to execute the query on. Defaults to null meaning all indexes
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search.html#search-multi-index
|
|
|
|
*/
|
|
|
|
public $index;
|
|
|
|
/**
|
|
|
|
* @var string|array the types to execute the query on. Defaults to null meaning all types
|
|
|
|
*/
|
|
|
|
public $type;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array|string array or json
|
|
|
|
*/
|
|
|
|
public $query;
|
|
|
|
|
|
|
|
// private function createUrl($endPoint = null)
|
|
|
|
// {
|
|
|
|
// if ($endPoint === null) {
|
|
|
|
// $endPoint = $this->api;
|
|
|
|
// }
|
|
|
|
// if ($this->index === null && $this->type === null) {
|
|
|
|
// return '/' . $endPoint;
|
|
|
|
// }
|
|
|
|
// $index = $this->index;
|
|
|
|
// if ($index === null) {
|
|
|
|
// $index = '_all';
|
|
|
|
// } elseif (is_array($index)) {
|
|
|
|
// $index = implode(',', $index);
|
|
|
|
// }
|
|
|
|
// $type = $this->type;
|
|
|
|
// if (is_array($type)) {
|
|
|
|
// $type = implode(',', $type);
|
|
|
|
// }
|
|
|
|
// return '/' . $index . '/' . (empty($type) ? '' : $type . '/') . $endPoint;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public function queryAll()
|
|
|
|
// {
|
|
|
|
// $query = $this->query;
|
|
|
|
// if (empty($query)) {
|
|
|
|
// $query = '{}';
|
|
|
|
// }
|
|
|
|
// if (is_array($query)) {
|
|
|
|
// $query = Json::encode($query);
|
|
|
|
// }
|
|
|
|
// $http = $this->db->http();
|
|
|
|
// $response = $http->post($this->createUrl(), null, $query)->send();
|
|
|
|
// $data = Json::decode($response->getBody(true));
|
|
|
|
// // TODO store query meta data for later use
|
|
|
|
// $docs = array();
|
|
|
|
// switch ($this->api) {
|
|
|
|
// default:
|
|
|
|
// case '_search':
|
|
|
|
// if (isset($data['hits']['hits'])) {
|
|
|
|
// $docs = $data['hits']['hits'];
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
// case '_mget':
|
|
|
|
// if (isset($data['docs'])) {
|
|
|
|
// $docs = $data['docs'];
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// $rows = array();
|
|
|
|
// foreach($docs as $doc) {
|
|
|
|
// // TODO maybe return type info
|
|
|
|
// if (isset($doc['exists']) && !$doc['exists']) {
|
|
|
|
// continue;
|
|
|
|
// }
|
|
|
|
// $row = $doc['_source'];
|
|
|
|
// $row['id'] = $doc['_id'];
|
|
|
|
// $rows[] = $row;
|
|
|
|
// }
|
|
|
|
// return $rows;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public function queryOne()
|
|
|
|
// {
|
|
|
|
// // TODO set limit
|
|
|
|
// $rows = $this->queryAll();
|
|
|
|
// return reset($rows);
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// public function queryCount()
|
|
|
|
// {
|
|
|
|
// //http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-count.html
|
|
|
|
// $query = $this->query;
|
|
|
|
// if (empty($query)) {
|
|
|
|
// $query = '';
|
|
|
|
// }
|
|
|
|
// if (is_array($query)) {
|
|
|
|
// $query = Json::encode($query);
|
|
|
|
// }
|
|
|
|
// $http = $this->db->http();
|
|
|
|
// $response = $http->post($this->createUrl('_count'), null, $query)->send();
|
|
|
|
// $data = Json::decode($response->getBody(true));
|
|
|
|
// // TODO store query meta data for later use
|
|
|
|
// return $data['count'];
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Inserts a document into an index
|
|
|
|
* @param string $index
|
|
|
|
* @param string $type
|
|
|
|
* @param string|array $data json string or array of data to store
|
|
|
|
* @param null $id the documents id. If not specified Id will be automatically choosen
|
|
|
|
* @param array $options
|
|
|
|
* @return mixed
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-index_.html
|
|
|
|
*/
|
|
|
|
public function insert($index, $type, $data, $id = null, $options = [])
|
|
|
|
{
|
|
|
|
$body = is_array($data) ? Json::encode($data) : $data;
|
|
|
|
if ($id !== null) {
|
|
|
|
$response = $this->db->http()->put($this->createUrl([$index, $type, $id], $options), null, $body)->send();
|
|
|
|
} else {
|
|
|
|
$response = $this->db->http()->post($this->createUrl([$index, $type], $options), null, $body)->send();
|
|
|
|
}
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gets a document from the index
|
|
|
|
* @param $index
|
|
|
|
* @param $type
|
|
|
|
* @param $id
|
|
|
|
* @param array $options
|
|
|
|
* @return mixed
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-get.html
|
|
|
|
*/
|
|
|
|
public function get($index, $type, $id, $options = [])
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->post($this->createUrl([$index, $type, $id], $options))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gets a documents _source from the index (>=v0.90.1)
|
|
|
|
* @param $index
|
|
|
|
* @param $type
|
|
|
|
* @param $id
|
|
|
|
* @return mixed
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-get.html#_source
|
|
|
|
*/
|
|
|
|
public function getSource($index, $type, $id)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->head($this->createUrl([$index, $type, $id]))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO mget http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-multi-get.html
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gets a document from the index
|
|
|
|
* @param $index
|
|
|
|
* @param $type
|
|
|
|
* @param $id
|
|
|
|
* @return mixed
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-get.html
|
|
|
|
*/
|
|
|
|
public function exists($index, $type, $id)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->head($this->createUrl([$index, $type, $id]))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* deletes a document from the index
|
|
|
|
* @param $index
|
|
|
|
* @param $type
|
|
|
|
* @param $id
|
|
|
|
* @param array $options
|
|
|
|
* @return mixed
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-delete.html
|
|
|
|
*/
|
|
|
|
public function delete($index, $type, $id, $options = [])
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->delete($this->createUrl([$index, $type, $id], $options))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* updates a document
|
|
|
|
* @param $index
|
|
|
|
* @param $type
|
|
|
|
* @param $id
|
|
|
|
* @param array $options
|
|
|
|
* @return mixed
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-update.html
|
|
|
|
*/
|
|
|
|
public function update($index, $type, $id, $data, $options = [])
|
|
|
|
{
|
|
|
|
// TODO
|
|
|
|
$response = $this->db->http()->delete($this->createUrl([$index, $type, $id], $options))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO bulk http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/docs-bulk.html
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-create-index.html
|
|
|
|
*/
|
|
|
|
public function createIndex($index, $configuration = null)
|
|
|
|
{
|
|
|
|
$body = $configuration !== null ? Json::encode($configuration) : null;
|
|
|
|
$response = $this->db->http()->put($this->createUrl([$index]), null, $body)->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-delete-index.html
|
|
|
|
*/
|
|
|
|
public function deleteIndex($index)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->delete($this->createUrl([$index]))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-delete-index.html
|
|
|
|
*/
|
|
|
|
public function deleteAllIndexes()
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->delete($this->createUrl(['_all']))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-exists.html
|
|
|
|
*/
|
|
|
|
public function indexExists($index)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->head($this->createUrl([$index]))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-types-exists.html
|
|
|
|
*/
|
|
|
|
public function typeExists($index, $type)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->head($this->createUrl([$index, $type]))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-aliases.html
|
|
|
|
|
|
|
|
// TODO http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-update-settings.html
|
|
|
|
// TODO http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-get-settings.html
|
|
|
|
|
|
|
|
// TODO http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-warmers.html
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html
|
|
|
|
*/
|
|
|
|
public function openIndex($index)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->post($this->createUrl([$index, '_open']))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-open-close.html
|
|
|
|
*/
|
|
|
|
public function closeIndex($index)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->post($this->createUrl([$index, '_close']))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-status.html
|
|
|
|
*/
|
|
|
|
public function getIndexStatus($index = '_all')
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->get($this->createUrl([$index, '_status']))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-stats.html
|
|
|
|
// http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-segments.html
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-clearcache.html
|
|
|
|
*/
|
|
|
|
public function clearIndexCache($index)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->post($this->createUrl([$index, '_cache', 'clear']))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-flush.html
|
|
|
|
*/
|
|
|
|
public function flushIndex($index)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->post($this->createUrl([$index, '_flush']))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-refresh.html
|
|
|
|
*/
|
|
|
|
public function refreshIndex($index)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->post($this->createUrl([$index, '_refresh']))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-optimize.html
|
|
|
|
|
|
|
|
// TODO http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-gateway-snapshot.html
|
|
|
|
|
|
|
|
/**
|
|
|
|
* http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-put-mapping.html
|
|
|
|
*/
|
|
|
|
public function setMapping($index, $type, $mapping)
|
|
|
|
{
|
|
|
|
$body = $mapping !== null ? Json::encode($mapping) : null;
|
|
|
|
$response = $this->db->http()->put($this->createUrl([$index, $type, '_mapping']), null, $body)->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-get-mapping.html
|
|
|
|
*/
|
|
|
|
public function getMapping($index = '_all', $type = '_all')
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->get($this->createUrl([$index, $type, '_mapping']))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-put-mapping.html
|
|
|
|
*/
|
|
|
|
public function deleteMapping($index, $type)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->delete($this->createUrl([$index, $type]))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-get-field-mapping.html
|
|
|
|
*/
|
|
|
|
public function getFieldMapping($index, $type = '_all')
|
|
|
|
{
|
|
|
|
// TODO
|
|
|
|
$response = $this->db->http()->put($this->createUrl([$index, $type, '_mapping']))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-analyze.html
|
|
|
|
*/
|
|
|
|
public function analyze($options, $index = null)
|
|
|
|
{
|
|
|
|
// TODO
|
|
|
|
$response = $this->db->http()->put($this->createUrl([$index, $type, '_mapping']))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-templates.html
|
|
|
|
*/
|
|
|
|
public function createTemplate($name, $pattern, $settings, $mappings, $order = 0)
|
|
|
|
{
|
|
|
|
$body = Json::encode([
|
|
|
|
'template' => $pattern,
|
|
|
|
'order' => $order,
|
|
|
|
'settings' => (object) $settings,
|
|
|
|
'mappings' => (object) $settings,
|
|
|
|
]);
|
|
|
|
$response = $this->db->http()->put($this->createUrl(['_template', $name]), null, $body)->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-templates.html
|
|
|
|
*/
|
|
|
|
public function deleteTemplate($name)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->delete($this->createUrl(['_template', $name]))->send();
|
|
|
|
return $response->getStatusCode() == 200;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @see http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-templates.html
|
|
|
|
*/
|
|
|
|
public function getTemplate($name)
|
|
|
|
{
|
|
|
|
$response = $this->db->http()->get($this->createUrl(['_template', $name]))->send();
|
|
|
|
return Json::decode($response->getBody(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
private function createUrl($path, $options = [])
|
|
|
|
{
|
|
|
|
$url = implode('/', array_map(function($a) {
|
|
|
|
return urlencode(is_array($a) ? implode(',', $a) : $a);
|
|
|
|
}, $path));
|
|
|
|
|
|
|
|
if (!empty($options)) {
|
|
|
|
$url .= '?' . http_build_query($options);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $url;
|
|
|
|
}
|
|
|
|
}
|