Navigation Menu

Skip to content
This repository has been archived by the owner on Apr 22, 2022. It is now read-only.

Enhancement of ElasticSearch support, SearchManager, and Serialization #77

Merged
merged 14 commits into from Jun 19, 2013
41 changes: 41 additions & 0 deletions lib/Doctrine/Search/Configuration.php
Expand Up @@ -23,6 +23,9 @@
use Doctrine\Common\Cache\ArrayCache;
use Doctrine\Search\Mapping\ClassMetadataFactory;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Search\SerializerInterface;
use Doctrine\Search\Serializer\CallbackSerializer;
use Doctrine\Common\Persistence\ObjectManager;

/**
* Configuration SearchManager
Expand Down Expand Up @@ -134,4 +137,42 @@ public function getClassMetadataFactory()
return $this->attributes['classMetadataFactory'];
}

/**
* Sets an entity serializer
*
* @param SerializerInterface $serializer
*/
public function setEntitySerializer(SerializerInterface $serializer)
{
$this->attributes['serializer'] = $serializer;
}

/**
* Gets the entity serializer or provides a default if not set
*
* @return SerializerInterface
*/
public function getEntitySerializer()
{
if(isset($this->attributes['serializer'])) {
return $this->attributes['serializer'];
}
return new CallbackSerializer();
}

/**
* @param ObjectManager $entityManager
*/
public function setEntityManager(ObjectManager $entityManager)
{
$this->attributes['entityManager'] = $serializer;
}

/**
* @return ObjectManager
*/
public function getEntityManager()
{
if(isset($this->attributes['entityManager'])) return $this->attributes['entityManager'];
}
}
120 changes: 104 additions & 16 deletions lib/Doctrine/Search/ElasticSearch/Client.php
Expand Up @@ -19,7 +19,15 @@

namespace Doctrine\Search\ElasticSearch;



use Doctrine\Search\SearchClientInterface;
use Doctrine\Search\Mapping\ClassMetadata;
use Elastica\Client as ElasticaClient;
use Elastica\Type\Mapping;
use Elastica\Document;
use Elastica\Index;
use Elastica\Query\MatchAll;

/**
* SearchManager for ElasticSearch-Backend
Expand All @@ -31,51 +39,131 @@
class Client implements SearchClientInterface
{
/**
* @var \Elastica_Client
* @var ElasticaClient
*/
private $client;

/**
* @param \Elastica_Client $client
* @param ElasticaClient $client
*/
public function __construct(\Elastica_Client $client)
public function __construct(ElasticaClient $client)
{
$this->client = $client;
}

/**
* {@inheritDoc}
*/
public function addDocuments($index, $type, array $documents)
{
$type = $this->getIndex($index)->getType($type);

$batch = array();
foreach($documents as $id => $document)
{
$batch[] = new Document($id, $document);
}

$type->addDocuments($batch);
}

/**
* {@inheritDoc}
*/
public function removeDocuments($index, $type, array $documents)
{
$type = $this->getIndex($index)->getType($type);
$type->deleteIds(array_keys($documents));
}

/**
* {@inheritDoc}
*/
public function removeAll($index, $type)
{
$type = $this->getIndex($index)->getType($type);
$type->deleteByQuery(new MatchAll());
}

/**
* {@inheritDoc}
*/
public function find($index, $type, $query)
{
$index = $this->client->getIndex($index);
return iterator_to_array($index->search($query));
$type = $this->getIndex($index)->getType($type);
return $type->search($query);
}

/**
* {@inheritDoc}
*/
public function createIndex($index, $type, array $data)
public function createIndex($name, array $config = array())
{
$index = $this->client->getIndex($index);
$index->create();

$index->addDocuments($data);
$index = $this->getIndex($name);
$index->create($config, true);
return $index;
}

/**
* {@inheritDoc}
*/
public function deleteIndex($index)
public function getIndex($name)
{
$index = $this->client->getIndex($index);
$index->delete();
return $this->client->getIndex($name);
}


/**
* {@inheritDoc}
*/
public function deleteIndex($index)
{
$this->getIndex($index)->delete();
}

/**
* {@inheritDoc}
*/
public function bulkSearch(array $data)
public function createType(ClassMetadata $metadata)
{
$type = $this->getIndex($metadata->index)->getType($metadata->type);
$properties = $this->getMapping($metadata->fieldMappings);

$mapping = new Mapping($type, $properties);
$mapping->disableSource($metadata->source);
$mapping->setParam('_boost', array('name' => '_boost', 'null_value' => $metadata->boost));
$mapping->send();

return $type;
}

/**
* Generates property mapping from entity annotations
*
* @param array $fieldMapping
*/
protected function getMapping($fieldMapping)
{
$properties = array();

foreach($fieldMapping as $propertyName => $fieldMapping)
{
if(isset($fieldMapping->name)) $propertyName = $fieldMapping->name;
$properties[$propertyName]['type'] = $fieldMapping->type;
if(isset($fieldMapping->includeInAll)) $properties[$propertyName]['include_in_all'] = $fieldMapping->includeInAll;
if(isset($fieldMapping->index)) $properties[$propertyName]['index'] = $fieldMapping->index;
if(isset($fieldMapping->boost)) $properties[$propertyName]['boost'] = $fieldMapping->boost;

if($fieldMapping->type == 'multi_field' && isset($fieldMapping->fields))
{
$properties[$propertyName]['fields'] = $this->getMapping($fieldMapping->fields);
}

if(in_array($fieldMapping->type, array('nested', 'object')) && isset($fieldMapping->properties))
{
$properties[$propertyName]['properties'] = $this->getMapping($fieldMapping->properties);
}
}

return $properties;
}
}
75 changes: 59 additions & 16 deletions lib/Doctrine/Search/Mapping/Annotations/DoctrineAnnotations.php
Expand Up @@ -29,12 +29,13 @@
*/
class Searchable extends Annotation
{
/**
* @var string $index;
/**
* @var string $index
*/
public $index;
/**
* @var string $type;

/**
* @var string $type
*/
public $type;
}
Expand All @@ -45,27 +46,41 @@ class Searchable extends Annotation
*/
final class ElasticSearchable extends Searchable
{
/**
* @var int $numberOfShards;
/**
* @var int $numberOfShards
*/
public $numberOfShards;
/**

/**
* @var int $numnberOfReplicas
*/
public $numberOfReplicas;
/**
* @var string $op_type;

/**
* @var string $op_type
*/
public $opType;
/**
* @var float $parent;

/**
* @var float $parent
*/
public $parent;

/**
* TTL in milliseconds
* @var int $timeToLive
*/
public $timeToLive;

/**
* @var float
*/
public $boost;

/**
* @var boolean
*/
public $source;
}

/**
Expand All @@ -74,10 +89,20 @@ final class ElasticSearchable extends Searchable
*/
class Field extends Annotation
{
/**
* @var float
/**
* @var float
*/
public $boost;

/**
* @var string
*/
public $type;

/**
* @var string
*/
public $name;
}

/**
Expand All @@ -91,9 +116,27 @@ final class SolrField extends Field

/**
* @Annotation
* @Target("PROPERTY")
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
*/
final class ElasticField extends Field
{
/* configuration */
}
/**
* @var boolean
*/
public $includeInAll;

/**
* @var string
*/
public $index;

/**
* @var array
*/
public $fields;

/**
* @var array
*/
public $properties;
}