Skip to content

Commit

Permalink
Adding setup and search demo
Browse files Browse the repository at this point in the history
  • Loading branch information
MrHash committed Apr 10, 2014
1 parent f10167b commit 1133a80
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
phpunit.xml
composer.lock
vendor/
vendor/
demo/vendor/
45 changes: 45 additions & 0 deletions demo/ElasticSearch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

require_once 'config.php';

use Doctrine\Common\ClassLoader;
use Doctrine\Search\Configuration;
use Doctrine\Common\EventManager;
use Doctrine\Search\SearchManager;
use Elastica\Client;
use Doctrine\Search\ElasticSearch\Client as ElasticaAdapter;
use Doctrine\Search\Serializer\JMSSerializer;
use JMS\Serializer\SerializationContext;

class ElasticSearch
{
public static function get()
{
//Entity loader
$entities = Config::getEntityNamespacePath();
$cl = new ClassLoader($entities['namespace'], $entities['path']);
$cl->register();

//Annotation metadata driver
$config = new Configuration();
$md = $config->newDefaultAnnotationDriver(array($entities['namespace']));
$config->setMetadataDriverImpl($md);

//Set and configure preferred serializer for persistence
//If using serialaztion groups you can sepcify the names here
$config->setEntitySerializer(new JMSSerializer(
SerializationContext::create()->setGroups('store')
));

//Add event listeners here
$eventManager = new EventManager();
//$eventManager->addEventListener('prePersist', $listener);

//Get the search manager
return new SearchManager(
$config,
new ElasticaAdapter(new Client(Config::getServers())),
$eventManager
);
}
}
26 changes: 26 additions & 0 deletions demo/Entities/Email.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Entities;

use JMS\Serializer\Annotation as JMS;

class Email
{
/**
* @JMS\Type("string")
* @JMS\Expose @JMS\Groups({"privateapi", "store"})
*/
private $email;

/**
* @JMS\Type("DateTime")
* @JMS\Expose @JMS\Groups({"privateapi", "store"})
*/
private $createdAt;

public function __construct($email)
{
$this->email = $email;
$this->createdAt = new \DateTime('now');
}
}
100 changes: 100 additions & 0 deletions demo/Entities/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

namespace Entities;

use JMS\Serializer\Annotation as JMS;
use Doctrine\Search\Mapping\Annotations as MAP;

/**
* @JMS\ExclusionPolicy("all")
* @MAP\ElasticSearchable(index="searchdemo", type="users", source=true)
*/
class User
{
/**
* @MAP\Id
* @JMS\Type("string")
* @JMS\Expose @JMS\Groups({"public"})
*
* Using Serialization groups allows us to provide a version of serialized object
* for storage, and a different one for passing into a document output renderer, such
* as might be useful for an api.
*/
private $id;

/**
* @JMS\Type("string")
* @JMS\Expose @JMS\Groups({"api", "store"})
* @MAP\ElasticField(type="string", includeInAll=false, index="no")
*/
private $name;

/**
* @JMS\Type("string")
* @JMS\Expose @JMS\Groups({"api", "store"})
* @MAP\ElasticField(type="multi_field", fields={
* @MAP\ElasticField(name="username", type="string", includeInAll=true, analyzer="whitespace"),
* @MAP\ElasticField(name="username.term", type="string", includeInAll=false, index="not_analyzed")
* })
*/
private $username;

/**
* @JMS\Type("array")
* @JMS\Expose @JMS\Groups({"store"})
* @MAP\ElasticField(type="string", includeInAll=false, index="not_analyzed")
*/
private $friends = array();

/**
* @JMS\Type("array<Entities\Email>")
* @JMS\Expose @JMS\Groups({"privateapi", "store"})
* @MAP\ElasticField(type="nested", properties={
* @MAP\ElasticField(name="email", type="string", includeInAll=false, index="not_analyzed"),
* @MAP\ElasticField(name="createdAt", type="date")
* })
*/
private $emails = array();



public function getId()
{
if(!$this->id) $this->id = uniqid();
return $this->id;
}

public function setName($name)
{
$this->name = $name;
}

public function setUsername($username)
{
$this->username = $username;
}

public function getUsername()
{
return $this->username;
}

public function getFriends()
{
return $this->friends;
}

public function addFriend(User $user)
{
if(!in_array($user->getId(), $this->friends))
{
$this->friends[] = $user->getId();
}
}

public function addEmail(Email $email)
{
$this->emails[] = $email;
}
}

5 changes: 5 additions & 0 deletions demo/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
1. Make sure you have composer installed
2. Run `composer update` to install dependencies. Check composer.json for correct version of Elastica which corresponds to your ES installation.
3. Make sure you have ES running and modify config.php to point at it.
4. Run `php build.php` from command line to create the index and fixtures
5. Run `php index.php` from the command line or navigate to in the browser
49 changes: 49 additions & 0 deletions demo/build.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

require_once 'vendor/autoload.php';
require_once 'ElasticSearch.php';

use Entities\User;
use Entities\Email;

$sm = ElasticSearch::get();

$client = $sm->getClient();
$metadatas = $sm->getMetadataFactory()->getAllMetadata();

// Delete indexes
foreach($metadatas as $metadata)
{
if($client->getIndex($metadata->index)->exists())
{
$client->deleteIndex($metadata->index);
}
}

// Recreate indexes and types
foreach($metadatas as $oMetadata)
{
if(!$client->getIndex($metadata->index)->exists())
{
$client->createIndex($metadata->index);
}
$client->createType($metadata);
}


//Install fixtures here... can use Doctrine/data-fixtures package with
//special SearchManager adapter if required.
$user1 = new User();
$user1->setName('Hash');
$user1->setUsername('mrhash');
$user1->addEmail(new Email('[email protected]'));

$user2 = new User();
$user2->setName('Timothy Leary');
$user2->setUsername('timmyl');
$user2->addEmail(new Email('[email protected]'));
$user2->addEmail(new Email('[email protected]'));
$user2->addFriend($user1);

$sm->persist(array($user1, $user2));
$sm->flush();
15 changes: 15 additions & 0 deletions demo/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"repositories":[
{
"type":"vcs",
"url":"http://github.com/MrHash/search"
}
],
"require":{
"doctrine/common":"2.3.*",
"doctrine/dbal":"2.3.*",
"jms/serializer":"0.15.0",
"ruflin/elastica":"v1.0.1.2",
"doctrine/search":"dev-master"
}
}
20 changes: 20 additions & 0 deletions demo/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

Doctrine\Common\Annotations\AnnotationRegistry::registerLoader('class_exists');

class Config
{
//List of available servers
public static function getServers()
{
return array(
array('host' => 'localhost', 'port' => 9200)
);
}

//Entities namespace and location
public static function getEntityNamespacePath()
{
return array('namespace' => 'Entities', 'path' => '.');
}
}
40 changes: 40 additions & 0 deletions demo/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

require_once 'vendor/autoload.php';
require_once 'ElasticSearch.php';

//Get the search manager
$sm = ElasticSearch::get();



//Execute a direct Elastica term search
$query = new Elastica\Filter\Term(array('username' => 'timmyl'));
$results = $sm->getRepository('Entities\User')->search($query);

foreach($results as $user)
{
print_r($user);
}



//Execute a single term lookup, modify and persist
$user = $sm->getRepository('Entities\User')->findOneBy(array('username' => 'mrhash'));
print_r($user);
$user->setName('New name');
$sm->persist($user);
$sm->flush();



//Execute a single lookup with no results
try
{
$user = $sm->find('Entities\User', 'unknownid');
}
catch(Doctrine\Search\Exception\NoResultException $exception)
{
print_r($exception->getMessage());
}

0 comments on commit 1133a80

Please sign in to comment.