Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 4 commits
  • 5 files changed
  • 0 commit comments
  • 1 contributor
Showing with 229 additions and 20 deletions.
  1. +16 −3 README.markdown
  2. +42 −11 src/ElasticSearch/Client.php
  3. +69 −0 src/ElasticSearch/Mapping.php
  4. +3 −6 tests/units/Client.php
  5. +99 −0 tests/units/Mapping.php
View
19 README.markdown
@@ -37,13 +37,26 @@ $es->get($id);
$es->search('title:cool');
```
+### Creating mapping
+
+```php
+<?php
+$es->map(array(
+ 'title' => array(
+ 'type' => 'string',
+ 'index' => 'analyzed'
+ )
+));
+```
+
### Search multiple indexes or types
```php
<?php
-$es->setIndex(array("one", "two"));
-$es->setType(array("mytype", "other-type"));
-$es->search('title:cool');
+$results = $es
+ ->setIndex(array("one", "two"))
+ ->setType(array("mytype", "other-type"))
+ ->search('title:cool');
```
### Using the Query DSL
View
53 src/ElasticSearch/Client.php
@@ -32,7 +32,7 @@ class Client {
);
private $transport, $index, $type;
-
+
/**
* Construct search client
*
@@ -42,11 +42,8 @@ class Client {
* @param string $type
*/
public function __construct($transport, $index = null, $type = null) {
- $this->index = $index;
- $this->type = $type;
$this->transport = $transport;
- $this->transport->setIndex($index);
- $this->transport->setType($type);
+ $this->setIndex($index)->setType($type);
}
/**
@@ -90,7 +87,7 @@ public function config($config = null) {
if (is_array($config))
$this->_config = $config + $this->_config;
}
-
+
/**
* Change what index to go against
* @return void
@@ -101,8 +98,9 @@ public function setIndex($index) {
$index = implode(",", array_filter($index));
$this->index = $index;
$this->transport->setIndex($index);
+ return $this;
}
-
+
/**
* Change what types to act against
* @return void
@@ -113,8 +111,9 @@ public function setType($type) {
$type = implode(",", array_filter($type));
$this->type = $type;
$this->transport->setType($type);
+ return $this;
}
-
+
/**
* Fetch a document by its id
*
@@ -124,12 +123,44 @@ public function setType($type) {
public function get($id, $verbose=false) {
return $this->request(array($this->type, $id), "GET");
}
-
+
+ /**
+ * Puts a mapping on index
+ *
+ * @param array|object $mapping
+ */
+ public function map($mapping, array $config = array()) {
+ if (is_array($mapping)) $mapping = new Mapping($mapping);
+ $mapping->config($config);
+
+ try {
+ $type = $mapping->config('type');
+ }
+ catch (\Exception $e) {} // No type is cool
+ if (isset($type) && !$this->passesTypeConstraint($type)) {
+ throw new Exception("Cant create mapping due to type constraint mismatch");
+ }
+
+ return $this->request(array('_mapping'), 'PUT', $mapping->export(), true);
+ }
+
+ protected function passesTypeConstraint($constraint) {
+ if (is_string($constraint)) $constraint = array($constraint);
+ $currentType = explode(',', $this->type);
+ $includeTypes = array_intersect($constraint, $currentType);
+ return ($constraint && count($includeTypes) === count($constraint));
+ }
+
/**
* Perform a request
*
* @return array
- * @param mixed $id Optional
+ * @param mixed $path Request path to use.
+ * `type` is prepended to this path inside request
+ * @param string $method HTTP verb to use
+ * @param mixed $payload Array of data to be json-encoded
+ * @param bool $verbose Controls response data, if `false`
+ * only `_source` of response is returned
*/
public function request($path, $method, $payload = false, $verbose=false) {
$path = array_merge((array) $this->type, (array) $path);
@@ -177,7 +208,7 @@ public function search($query) {
public function delete($id=false, array $options = array()) {
return $this->transport->delete($id, $options);
}
-
+
/**
* Flush this index/type combination
*
View
69 src/ElasticSearch/Mapping.php
@@ -0,0 +1,69 @@
+<?php // vim:set ts=4 sw=4 et:
+
+namespace ElasticSearch;
+
+/**
+ * This file is part of the ElasticSearch PHP client
+ *
+ * (c) Raymond Julin <raymond.julin@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+class Mapping {
+
+ protected $properties = array();
+ protected $config = array();
+
+ /**
+ * Build mapping data
+ *
+ * @return ElasticSearch\Mapping
+ */
+ public function __construct(array $properties = array(), array $config = array()) {
+ $this->properties = $properties;
+ $this->config = $config;
+ }
+
+ /**
+ * Export mapping data as a json-ready array
+ *
+ * @return string
+ */
+ public function export() {
+ return array(
+ 'properties' => $this->properties
+ );
+ }
+
+ /**
+ * Add or overwrite existing field by name
+ *
+ * @param string $field
+ * @param string|array $config
+ * @return $this
+ */
+ public function field($field, $config = array()) {
+ if (is_string($config)) $config = array('type' => $config);
+ $this->properties[$field] = $config;
+ return $this;
+ }
+
+ /**
+ * Get or set a config
+ *
+ * @param string $key
+ * @param mixed $value
+ */
+ public function config($key, $value = null) {
+ if (is_array($key))
+ $this->config = $key + $this->config;
+ else {
+ if ($value !== null) $this->config[$key] = $value;
+ if (!isset($this->config[$key]))
+ throw new \Exception("Configuration key `type` is not set");
+ return $this->config[$key];
+ }
+ }
+}
View
9 tests/units/Client.php
@@ -136,16 +136,13 @@ public function testSearchMultipleIndexes()
$secondaryIndex = 'test-index2';
$doc = array('title' => $tag);
$options = array('refresh' => true);
- $client->setIndex($secondaryIndex);
- $client->index($doc, false, $options);
- $client->setIndex($primaryIndex);
- $client->index($doc, false, $options);
+ $client->setIndex($secondaryIndex)->index($doc, false, $options);
+ $client->setIndex($primaryIndex)->index($doc, false, $options);
$indexes = array($primaryIndex, $secondaryIndex);
// Use both indexes when searching
- $client->setIndex($indexes);
- $resp = $client->search("title:$tag");
+ $resp = $client->setIndex($indexes)->search("title:$tag");
$this->assert->array($resp)->hasKey('hits')
->array($resp['hits'])->hasKey('total')
View
99 tests/units/Mapping.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace ElasticSearch\tests\units;
+
+require_once getcwd() . '/vendor/autoload.php';
+
+use \mageekguy\atoum;
+
+class Mapping extends atoum\test
+{
+ public function testMapCreate() {
+ $mapping = new \ElasticSearch\Mapping(array(
+ 'tweet' => array(
+ 'type' => 'string'
+ ),
+ 'user.name' => array(
+ 'index' => 'not_analyzed'
+ )
+ ));
+
+ $jsonBody = $mapping->export();
+
+ $this->assert->array($jsonBody)
+ ->isNotEmpty()
+ ->hasSize(1)
+ ->array($jsonBody['properties'])
+ ->hasSize(2);
+
+ $properties = $jsonBody['properties'];
+
+ $this->assert->array($properties['tweet'])
+ ->isNotEmpty()
+ ->isEqualTo(array(
+ 'type' => 'string'
+ ));
+
+ $this->assert->array($properties['user.name'])
+ ->isNotEmpty()
+ ->isEqualTo(array(
+ 'index' => 'not_analyzed'
+ ));
+ }
+
+ public function testAddMoreFieldsToMapping() {
+ $mapping = new \ElasticSearch\Mapping;
+
+ $exported = $mapping->field('tweet', array(
+ 'type' => 'string'
+ ))->export();
+
+ // TODO Does atoum have a prettier interface for this drill down?
+ $this->assert->array($exported)->isNotEmpty()
+ ->isEqualTo(array(
+ 'properties' => array(
+ 'tweet' => array('type' => 'string')
+ )
+ ));
+ }
+
+ public function testAddFieldWithTypeLazy() {
+ $mapping = new \ElasticSearch\Mapping;
+ // Basic mappings:
+ $exported = $mapping->field('tweet', 'string')->export();
+ $this->assert->array($exported)->isNotEmpty()
+ ->isEqualTo(array(
+ 'properties' => array(
+ 'tweet' => array('type' => 'string')
+ )
+ ));
+ }
+
+ public function testAddTypeConstrainedMapping() {
+ $mapping = new \ElasticSearch\Mapping(array(
+ 'tweet' => array(
+ 'type' => 'string'
+ )
+ ), array('type' => 'tweet'));
+
+ $exported = $mapping->export();
+ $this->assert->array($exported)->isNotEmpty()
+ ->hasKey('properties')->notHasKey('type');
+ }
+
+ // Integrate and perform query
+ public function testMapFields() {
+ $client = \ElasticSearch\Client::connection(array(
+ 'index' => 'test-index',
+ 'type' => 'test-type'
+ ));
+ $client->index(array(
+ 'tweet' => 'ElasticSearch is awesome'
+ ));
+ $response = $client->map(array(
+ 'tweet' => array('type' => 'string')
+ ));
+
+ $this->assert->array($response)->isNotEmpty();
+ }
+}

No commit comments for this range

Something went wrong with that request. Please try again.