| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558 |
- <?php
- namespace Elastica;
- use Elastica\Exception\InvalidException;
- use Elastica\Exception\NotFoundException;
- use Elastica\Exception\RuntimeException;
- use Elastica\ResultSet\BuilderInterface;
- use Elastica\Script\AbstractScript;
- use Elastica\Type\Mapping;
- use Elasticsearch\Endpoints\AbstractEndpoint;
- use Elasticsearch\Endpoints\Delete;
- use Elasticsearch\Endpoints\DeleteByQuery;
- use Elasticsearch\Endpoints\Indices\Mapping\Get;
- use Elasticsearch\Endpoints\Indices\Type\Exists;
- /**
- * Elastica type object.
- *
- * elasticsearch has for every types as a substructure. This object
- * represents a type inside a context
- * The hierarchy is as following: client -> index -> type -> document
- *
- * @author Nicolas Ruflin <spam@ruflin.com>
- */
- class Type implements SearchableInterface
- {
- /**
- * Index.
- *
- * @var \Elastica\Index Index object
- */
- protected $_index;
- /**
- * Type name.
- *
- * @var string Type name
- */
- protected $_name;
- /**
- * @var array|string A callable that serializes an object passed to it
- */
- protected $_serializer;
- /**
- * Creates a new type object inside the given index.
- *
- * @param \Elastica\Index $index Index Object
- * @param string $name Type name
- */
- public function __construct(Index $index, $name)
- {
- $this->_index = $index;
- $this->_name = $name;
- }
- /**
- * Adds the given document to the search index.
- *
- * @param \Elastica\Document $doc Document with data
- *
- * @return \Elastica\Response
- */
- public function addDocument(Document $doc)
- {
- $endpoint = new \Elasticsearch\Endpoints\Index();
- if (null !== $doc->getId() && '' !== $doc->getId()) {
- $endpoint->setID($doc->getId());
- }
- $options = $doc->getOptions(
- [
- 'version',
- 'version_type',
- 'routing',
- 'percolate',
- 'parent',
- 'op_type',
- 'consistency',
- 'replication',
- 'refresh',
- 'timeout',
- 'pipeline',
- ]
- );
- $endpoint->setBody($doc->getData());
- $endpoint->setParams($options);
- $response = $this->requestEndpoint($endpoint);
- $data = $response->getData();
- // set autogenerated id to document
- if (($doc->isAutoPopulate()
- || $this->getIndex()->getClient()->getConfigValue(['document', 'autoPopulate'], false))
- && $response->isOk()
- ) {
- if (!$doc->hasId()) {
- if (isset($data['_id'])) {
- $doc->setId($data['_id']);
- }
- }
- if (isset($data['_version'])) {
- $doc->setVersion($data['_version']);
- }
- }
- return $response;
- }
- /**
- * @param $object
- * @param Document $doc
- *
- * @throws Exception\RuntimeException
- *
- * @return Response
- */
- public function addObject($object, Document $doc = null)
- {
- if (!isset($this->_serializer)) {
- throw new RuntimeException('No serializer defined');
- }
- $data = call_user_func($this->_serializer, $object);
- if (!$doc) {
- $doc = new Document();
- }
- $doc->setData($data);
- return $this->addDocument($doc);
- }
- /**
- * Update document, using update script. Requires elasticsearch >= 0.19.0.
- *
- * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html
- *
- * @param \Elastica\Document|\Elastica\Script\AbstractScript $data Document with update data
- * @param array $options array of query params to use for query. For possible options check es api
- *
- * @throws \Elastica\Exception\InvalidException
- *
- * @return \Elastica\Response
- */
- public function updateDocument($data, array $options = [])
- {
- if (!($data instanceof Document) && !($data instanceof AbstractScript)) {
- throw new \InvalidArgumentException('Data should be a Document or Script');
- }
- if (!$data->hasId()) {
- throw new InvalidException('Document or Script id is not set');
- }
- return $this->getIndex()->getClient()->updateDocument(
- $data->getId(),
- $data,
- $this->getIndex()->getName(),
- $this->getName(),
- $options
- );
- }
- /**
- * Uses _bulk to send documents to the server.
- *
- * @param array|\Elastica\Document[] $docs Array of Elastica\Document
- * @param array $options Array of query params to use for query. For possible options check es api
- *
- * @return \Elastica\Bulk\ResponseSet
- *
- * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
- */
- public function updateDocuments(array $docs, array $options = [])
- {
- foreach ($docs as $doc) {
- $doc->setType($this->getName());
- }
- return $this->getIndex()->updateDocuments($docs, $options);
- }
- /**
- * Uses _bulk to send documents to the server.
- *
- * @param array|\Elastica\Document[] $docs Array of Elastica\Document
- * @param array $options Array of query params to use for query. For possible options check es api
- *
- * @return \Elastica\Bulk\ResponseSet
- *
- * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
- */
- public function addDocuments(array $docs, array $options = [])
- {
- foreach ($docs as $doc) {
- $doc->setType($this->getName());
- }
- return $this->getIndex()->addDocuments($docs, $options);
- }
- /**
- * Uses _bulk to send documents to the server.
- *
- * @param object[] $objects
- * @param array $options Array of query params to use for query. For possible options check es api
- *
- * @return Bulk\ResponseSet
- *
- * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
- */
- public function addObjects(array $objects, array $options = [])
- {
- if (!isset($this->_serializer)) {
- throw new RuntimeException('No serializer defined');
- }
- $docs = [];
- foreach ($objects as $object) {
- $data = call_user_func($this->_serializer, $object);
- $doc = new Document();
- $doc->setData($data);
- $doc->setType($this->getName());
- $docs[] = $doc;
- }
- return $this->getIndex()->addDocuments($docs, $options);
- }
- /**
- * Get the document from search index.
- *
- * @param string $id Document id
- * @param array $options options for the get request
- *
- * @throws \Elastica\Exception\NotFoundException
- * @throws \Elastica\Exception\ResponseException
- *
- * @return \Elastica\Document
- */
- public function getDocument($id, $options = [])
- {
- $endpoint = new \Elasticsearch\Endpoints\Get();
- $endpoint->setID($id);
- $endpoint->setParams($options);
- $response = $this->requestEndpoint($endpoint);
- $result = $response->getData();
- if (!isset($result['found']) || false === $result['found']) {
- throw new NotFoundException('doc id '.$id.' not found');
- }
- if (isset($result['fields'])) {
- $data = $result['fields'];
- } elseif (isset($result['_source'])) {
- $data = $result['_source'];
- } else {
- $data = [];
- }
- $document = new Document($id, $data, $this->getName(), $this->getIndex());
- $document->setVersion($result['_version']);
- return $document;
- }
- /**
- * @param string $id
- * @param array|string $data
- *
- * @return Document
- */
- public function createDocument($id = '', $data = [])
- {
- $document = new Document($id, $data);
- $document->setType($this);
- return $document;
- }
- /**
- * Returns the type name.
- *
- * @return string Type name
- */
- public function getName()
- {
- return $this->_name;
- }
- /**
- * Sets value type mapping for this type.
- *
- * @param \Elastica\Type\Mapping|array $mapping Elastica\Type\MappingType object or property array with all mappings
- * @param array $query querystring when put mapping (for example update_all_types)
- *
- * @return \Elastica\Response
- */
- public function setMapping($mapping, array $query = [])
- {
- $mapping = Mapping::create($mapping);
- $mapping->setType($this);
- return $mapping->send($query);
- }
- /**
- * Returns current mapping for the given type.
- *
- * @return array Current mapping
- */
- public function getMapping()
- {
- $response = $this->requestEndpoint(new Get());
- $data = $response->getData();
- $mapping = array_shift($data);
- if (isset($mapping['mappings'])) {
- return $mapping['mappings'];
- }
- return [];
- }
- /**
- * Create search object.
- *
- * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object
- * @param int|array $options OPTIONAL Limit or associative array of options (option=>value)
- * @param BuilderInterface $builder
- *
- * @return Search
- */
- public function createSearch($query = '', $options = null, BuilderInterface $builder = null)
- {
- $search = $this->getIndex()->createSearch($query, $options, $builder);
- $search->addType($this);
- return $search;
- }
- /**
- * Do a search on this type.
- *
- * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object
- * @param int|array $options OPTIONAL Limit or associative array of options (option=>value)
- *
- * @return \Elastica\ResultSet with all results inside
- *
- * @see \Elastica\SearchableInterface::search
- */
- public function search($query = '', $options = null)
- {
- $search = $this->createSearch($query, $options);
- return $search->search();
- }
- /**
- * Count docs by query.
- *
- * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object
- *
- * @return int number of documents matching the query
- *
- * @see \Elastica\SearchableInterface::count
- */
- public function count($query = '')
- {
- $search = $this->createSearch($query);
- return $search->count();
- }
- /**
- * Returns index client.
- *
- * @return \Elastica\Index Index object
- */
- public function getIndex()
- {
- return $this->_index;
- }
- /**
- * @param \Elastica\Document $document
- *
- * @return \Elastica\Response
- */
- public function deleteDocument(Document $document)
- {
- $options = $document->getOptions(
- [
- 'version',
- 'version_type',
- 'routing',
- 'parent',
- 'replication',
- 'consistency',
- 'refresh',
- 'timeout',
- ]
- );
- return $this->deleteById($document->getId(), $options);
- }
- /**
- * Uses _bulk to delete documents from the server.
- *
- * @param array|\Elastica\Document[] $docs Array of Elastica\Document
- *
- * @return \Elastica\Bulk\ResponseSet
- *
- * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
- */
- public function deleteDocuments(array $docs)
- {
- foreach ($docs as $doc) {
- $doc->setType($this->getName());
- }
- return $this->getIndex()->deleteDocuments($docs);
- }
- /**
- * Deletes an entry by its unique identifier.
- *
- * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html
- *
- * @param int|string $id Document id
- * @param array $options
- *
- * @throws \InvalidArgumentException
- * @throws \Elastica\Exception\NotFoundException
- *
- * @return \Elastica\Response Response object
- */
- public function deleteById($id, array $options = [])
- {
- if (empty($id) || !trim($id)) {
- throw new \InvalidArgumentException();
- }
- $endpoint = new Delete();
- $endpoint->setID($id);
- $endpoint->setParams($options);
- $response = $this->requestEndpoint($endpoint);
- $responseData = $response->getData();
- if (isset($responseData['result']) && 'not_found' == $responseData['result']) {
- throw new NotFoundException('Doc id '.$id.' not found and can not be deleted');
- }
- return $response;
- }
- /**
- * Deletes the given list of ids from this type.
- *
- * @param array $ids
- * @param string|bool $routing Optional routing key for all ids
- *
- * @return \Elastica\Response Response object
- */
- public function deleteIds(array $ids, $routing = false)
- {
- return $this->getIndex()->getClient()->deleteIds($ids, $this->getIndex(), $this, $routing);
- }
- /**
- * Deletes entries in the db based on a query.
- *
- * @param \Elastica\Query|\Elastica\Query\AbstractQuery|string|array $query Query object
- * @param array $options Optional params
- *
- * @return \Elastica\Response
- *
- * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html
- */
- public function deleteByQuery($query, array $options = [])
- {
- $query = Query::create($query);
- $endpoint = new DeleteByQuery();
- $endpoint->setBody($query->toArray());
- $endpoint->setParams($options);
- return $this->requestEndpoint($endpoint);
- }
- /**
- * Makes calls to the elasticsearch server based on this type.
- *
- * @param string $path Path to call
- * @param string $method Rest method to use (GET, POST, DELETE, PUT)
- * @param array $data OPTIONAL Arguments as array
- * @param array $query OPTIONAL Query params
- *
- * @return \Elastica\Response Response object
- */
- public function request($path, $method, $data = [], array $query = [])
- {
- $path = $this->getName().'/'.$path;
- return $this->getIndex()->request($path, $method, $data, $query);
- }
- /**
- * Makes calls to the elasticsearch server with usage official client Endpoint based on this type.
- *
- * @param AbstractEndpoint $endpoint
- *
- * @return Response
- */
- public function requestEndpoint(AbstractEndpoint $endpoint)
- {
- $cloned = clone $endpoint;
- $cloned->setType($this->getName());
- return $this->getIndex()->requestEndpoint($cloned);
- }
- /**
- * Sets the serializer callable used in addObject.
- *
- * @see \Elastica\Type::addObject
- *
- * @param array|string $serializer @see \Elastica\Type::_serializer
- *
- * @return $this
- */
- public function setSerializer($serializer)
- {
- $this->_serializer = $serializer;
- return $this;
- }
- /**
- * Checks if the given type exists in Index.
- *
- * @return bool True if type exists
- */
- public function exists()
- {
- $response = $this->requestEndpoint(new Exists());
- return 200 === $response->getStatus();
- }
- }
|