Commit d442f056 by Carsten Brandt

elasticsearch find by simple condition

parent 955bf7da
...@@ -325,7 +325,7 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord ...@@ -325,7 +325,7 @@ abstract class ActiveRecord extends \yii\db\ActiveRecord
$values = $this->getDirtyAttributes($attributes); $values = $this->getDirtyAttributes($attributes);
$key = reset($this->primaryKey()); $key = reset($this->primaryKey());
$pk = $this->getAttribute($key); $pk = $this->getAttribute($key);
unset($values[$key]); //unset($values[$key]);
// save attributes // save attributes
if ($pk === null) { if ($pk === null) {
......
<?php
/**
* @author Carsten Brandt <mail@cebe.cc>
*/
namespace yii\elasticsearch;
use yii\base\Component;
use yii\helpers\Json;
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'];
}
}
\ No newline at end of file
...@@ -54,6 +54,23 @@ class Connection extends Component ...@@ -54,6 +54,23 @@ class Connection extends Component
} }
/** /**
* Creates a command for execution.
* @param string $query the SQL statement to be executed
* @return Command the DB command
*/
public function createCommand($query = null, $index = null, $type = null)
{
$this->open();
$command = new Command(array(
'db' => $this,
'query' => $query,
'index' => $index,
'type' => $type,
));
return $command;
}
/**
* Closes the connection when this component is being serialized. * Closes the connection when this component is being serialized.
* @return array * @return array
*/ */
......
...@@ -46,7 +46,7 @@ class QueryBuilder extends \yii\base\Object ...@@ -46,7 +46,7 @@ class QueryBuilder extends \yii\base\Object
{ {
$searchQuery = array(); $searchQuery = array();
$this->buildSelect($searchQuery, $query->select); $this->buildSelect($searchQuery, $query->select);
// $this->buildFrom(&$searchQuery, $query->from); // $this->buildFrom($searchQuery, $query->from);
$this->buildCondition($searchQuery, $query->where); $this->buildCondition($searchQuery, $query->where);
$this->buildOrderBy($searchQuery, $query->orderBy); $this->buildOrderBy($searchQuery, $query->orderBy);
$this->buildLimit($searchQuery, $query->limit, $query->offset); $this->buildLimit($searchQuery, $query->limit, $query->offset);
...@@ -209,7 +209,12 @@ class QueryBuilder extends \yii\base\Object ...@@ -209,7 +209,12 @@ class QueryBuilder extends \yii\base\Object
private function buildHashCondition(&$query, $condition) private function buildHashCondition(&$query, $condition)
{ {
$query['query']['term'] = $condition; foreach($condition as $attribute => $value) {
// ['query']['filteredQuery']
$query['filter']['bool']['must'][] = array(
'term' => array($attribute => $value),
);
}
return; // TODO more return; // TODO more
$parts = array(); $parts = array();
foreach ($condition as $column => $value) { foreach ($condition as $column => $value) {
......
...@@ -35,6 +35,6 @@ class Customer extends ActiveRecord ...@@ -35,6 +35,6 @@ class Customer extends ActiveRecord
public static function active($query) public static function active($query)
{ {
$query->andWhere('status=1'); $query->andWhere(array('status' => 1));
} }
} }
...@@ -4,7 +4,8 @@ namespace yiiunit\framework\elasticsearch; ...@@ -4,7 +4,8 @@ namespace yiiunit\framework\elasticsearch;
use yii\db\Query; use yii\db\Query;
use yii\elasticsearch\Connection; use yii\elasticsearch\Connection;
use yii\redis\ActiveQuery; use yii\elasticsearch\ActiveQuery;
use yii\helpers\Json;
use yiiunit\data\ar\elasticsearch\ActiveRecord; use yiiunit\data\ar\elasticsearch\ActiveRecord;
use yiiunit\data\ar\elasticsearch\Customer; use yiiunit\data\ar\elasticsearch\Customer;
use yiiunit\data\ar\elasticsearch\OrderItem; use yiiunit\data\ar\elasticsearch\OrderItem;
...@@ -80,6 +81,17 @@ class ActiveRecordTest extends ElasticSearchTestCase ...@@ -80,6 +81,17 @@ class ActiveRecordTest extends ElasticSearchTestCase
// $orderItem = new OrderItem(); // $orderItem = new OrderItem();
// $orderItem->setAttributes(array('order_id' => 3, 'item_id' => 2, 'quantity' => 1, 'subtotal' => 40.0), false); // $orderItem->setAttributes(array('order_id' => 3, 'item_id' => 2, 'quantity' => 1, 'subtotal' => 40.0), false);
// $orderItem->save(false); // $orderItem->save(false);
for($n = 0; $n < 20; $n++) {
$r = $db->http()->post('_count')->send();
$c = Json::decode($r->getBody(true));
if ($c['count'] != 11) {
usleep(100000);
} else {
return;
}
}
throw new \Exception('Unable to initialize elasticsearch data.');
} }
public function testFind() public function testFind()
...@@ -124,13 +136,14 @@ class ActiveRecordTest extends ElasticSearchTestCase ...@@ -124,13 +136,14 @@ class ActiveRecordTest extends ElasticSearchTestCase
// find count, sum, average, min, max, scalar // find count, sum, average, min, max, scalar
$this->assertEquals(3, Customer::find()->count()); $this->assertEquals(3, Customer::find()->count());
$this->assertEquals(6, Customer::find()->sum('id')); // $this->assertEquals(6, Customer::find()->sum('id'));
$this->assertEquals(2, Customer::find()->average('id')); // $this->assertEquals(2, Customer::find()->average('id'));
$this->assertEquals(1, Customer::find()->min('id')); // $this->assertEquals(1, Customer::find()->min('id'));
$this->assertEquals(3, Customer::find()->max('id')); // $this->assertEquals(3, Customer::find()->max('id'));
// scope // scope
$this->assertEquals(2, Customer::find()->active()->count()); $this->assertEquals(2, count(Customer::find()->active()->all()));
// $this->assertEquals(2, Customer::find()->active()->count());
// asArray // asArray
$customer = Customer::find()->where(array('id' => 2))->asArray()->one(); $customer = Customer::find()->where(array('id' => 2))->asArray()->one();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment