Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GeoShape Filters #568

Merged
merged 2 commits into from
Mar 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changes.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
CHANGES

2014-03-17
- Added filters: AbstractGeoShape, GeoShapePreIndexed, GeoShapeProvided #568

2014-03-15
- Percolate existing documents and add percolate options (#570)

Expand Down
50 changes: 50 additions & 0 deletions lib/Elastica/Filter/AbstractGeoShape.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace Elastica\Filter;

/**
* geo_shape filter
*
* Filter pre-indexed shape definitions
*
* @category Xodoa
* @package Elastica
* @author Bennie Krijger <benniekrijger@gmail.com>
* @link http://www.elasticsearch.org/guide/reference/query-dsl/geo-shape-filter/
*/
abstract class AbstractGeoShape extends AbstractFilter
{
const RELATION_INTERSECT = 'intersects';
const RELATION_DISJOINT = 'disjoint';
const RELATION_CONTAINS = 'within';

/**
* @var string $_path
*
* elasticsearch path of the pre-indexed shape
*/
protected $_path;

/**
* @var string $_relation
*
* the relation of the 2 shaped: intersects, disjoint, within
*/
protected $_relation = self::RELATION_INTERSECT;

/**
* @param string $relation
*/
public function setRelation($relation)
{
$this->_relation = $relation;
}

/**
* @return string
*/
public function getRelation()
{
return $this->_relation;
}
}
85 changes: 85 additions & 0 deletions lib/Elastica/Filter/GeoShapePreIndexed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace Elastica\Filter;

/**
* geo_shape filter for pre-indexed shapes
*
* Filter pre-indexed shape definitions
*
* @category Xodoa
* @package Elastica
* @author Bennie Krijger <benniekrijger@gmail.com>
* @link http://www.elasticsearch.org/guide/reference/query-dsl/geo-shape-filter/
*/
class GeoShapePreIndexed extends AbstractGeoShape
{
/**
* elasticsearch id of the pre-indexed shape
*
* @var string
*/
protected $_indexedId;

/**
* elasticsearch type of the pre-indexed shape
*
* @var string
*/
protected $_indexedType;

/**
* elasticsearch index of the pre-indexed shape
*
* @var string
*/
protected $_indexedIndex;

/**
* elasticsearch path/field name of the pre-indexed shape
*
* @var string
*/
protected $_indexedPath;

/**
* Construct geo_shape filter with a pre-indexed shape
*
* @param string $path The path/field of the shape searched
* @param string $indexedId Id of the pre-indexed shape
* @param string $indexedType Type of the pre-indexed shape
* @param string $indexedIndex Index of the pre-indexed shape
* @param string $indexedPath Path of the pre-indexed shape
*/
public function __construct($path, $indexedId, $indexedType, $indexedIndex, $indexedPath)
{
$this->_path = $path;
$this->_indexedId = $indexedId;
$this->_indexedType = $indexedType;
$this->_indexedIndex = $indexedIndex;
$this->_indexedPath = $indexedPath;
}

/**
* Converts filter to array
*
* @see \Elastica\Filter\AbstractFilter::toArray()
* @return array
*/
public function toArray()
{
return array(
'geo_shape' => array(
$this->_path => array(
'indexed_shape' => array(
'id' => $this->_indexedId,
'type' => $this->_indexedType,
'index' => $this->_indexedIndex,
'path' => $this->_indexedPath
),
'relation' => $this->_relation
)
)
);
}
}
74 changes: 74 additions & 0 deletions lib/Elastica/Filter/GeoShapeProvided.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Elastica\Filter;

/**
* geo_shape filter or provided shapes
*
* Filter provided shape definitions
*
* @category Xodoa
* @package Elastica
* @author BennieKrijger <benniekrijger@gmail.com>
* @link http://www.elasticsearch.org/guide/reference/query-dsl/geo-shape-filter/
*/
class GeoShapeProvided extends AbstractGeoShape
{
const TYPE_ENVELOPE = 'envelope';
const TYPE_MULTIPOINT = 'multipoint';
const TYPE_POINT = 'point';
const TYPE_MULTIPOLYGON = 'multipolygon';
const TYPE_LINESTRING = 'linestring';
const TYPE_POLYGON = 'polygon';

/**
* Type of the geo_shape
*
* @var string
*/
protected $_shapeType;

/**
* Coordinates making up geo_shape
*
* @var array Coordinates making up geo_shape
*/
protected $_coordinates;

/**
* Construct geo_shape filter
*
* @param string $path The path/field of the shape searched
* @param array $coordinates Points making up the shape
* @param string $shapeType Type of the geo_shape:
* point, envelope, linestring, polygon,
* multipoint or multipolygon
*/
public function __construct($path, array $coordinates, $shapeType = self::TYPE_ENVELOPE)
{
$this->_path = $path;
$this->_shapeType = $shapeType;
$this->_coordinates = $coordinates;
}

/**
* Converts filter to array
*
* @see \Elastica\Filter\AbstractFilter::toArray()
* @return array
*/
public function toArray()
{
return array(
'geo_shape' => array(
$this->_path => array(
'shape' => array(
'type' => $this->_shapeType,
'coordinates' => $this->_coordinates
),
'relation' => $this->_relation
),
)
);
}
}
90 changes: 90 additions & 0 deletions test/lib/Elastica/Test/Filter/GeoShapePreIndexedTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php


namespace Elastica\Test\Filter;

use Elastica\Filter\AbstractGeoShape;
use Elastica\Filter\GeoShapePreIndexed;
use Elastica\Query\MatchAll;
use Elastica\Query\Filtered;
use Elastica\Test\Base as BaseTest;

class GeoShapePreIndexedTest extends BaseTest
{
public function testGeoProvided()
{
$indexName = 'geo_shape_filter_test';
$index = $this->_createIndex($indexName);
$type = $index->getType('type');
$otherType = $index->getType('other_type');

// create mapping
$mapping = new \Elastica\Type\Mapping($type, array(
'location' => array(
'type' => 'geo_shape'
)
));
$type->setMapping($mapping);

// create other type mapping
$otherMapping = new \Elastica\Type\Mapping($type, array(
'location' => array(
'type' => 'geo_shape'
)
));
$otherType->setMapping($otherMapping);

// add type docs
$type->addDocument(new \Elastica\Document('1', array(
'location' => array(
"type" => "envelope",
"coordinates" => array(
array(0.0, 50.0),
array(50.0, 0.0)
)
)
)));

// add other type docs
$otherType->addDocument(new \Elastica\Document('2', array(
'location' => array(
"type" => "envelope",
"coordinates" => array(
array(25.0, 75.0),
array(75.0, 25.0)
)
)
)));

$index->optimize();
$index->refresh();

$gsp = new GeoShapePreIndexed(
'location', '1', 'type', 'elastica_'.$indexName, 'location'
);
$gsp->setRelation(AbstractGeoShape::RELATION_INTERSECT);

$expected = array(
'geo_shape' => array(
'location' => array(
'indexed_shape' => array(
'id' => '1',
'type' => 'type',
'index' => 'elastica_'.$indexName,
'path' => 'location'
),
'relation' => $gsp->getRelation()
)
)
);

$this->assertEquals($expected, $gsp->toArray());

$query = new Filtered(new MatchAll(), $gsp);
$results = $index->getType('type')->search($query);

$this->assertEquals(1, $results->count());

$index->delete();
}
}
Loading