vendor/ruflin/elastica/lib/Elastica/Type.php line 178

Open in your IDE?
  1. <?php
  2. namespace Elastica;
  3. use Elastica\Exception\InvalidException;
  4. use Elastica\Exception\NotFoundException;
  5. use Elastica\Exception\RuntimeException;
  6. use Elastica\ResultSet\BuilderInterface;
  7. use Elastica\Script\AbstractScript;
  8. use Elastica\Type\Mapping;
  9. use Elasticsearch\Endpoints\AbstractEndpoint;
  10. use Elasticsearch\Endpoints\Delete;
  11. use Elasticsearch\Endpoints\DeleteByQuery;
  12. use Elasticsearch\Endpoints\Indices\Mapping\Get;
  13. use Elasticsearch\Endpoints\Indices\Type\Exists;
  14. /**
  15.  * Elastica type object.
  16.  *
  17.  * elasticsearch has for every types as a substructure. This object
  18.  * represents a type inside a context
  19.  * The hierarchy is as following: client -> index -> type -> document
  20.  *
  21.  * @author   Nicolas Ruflin <spam@ruflin.com>
  22.  */
  23. class Type implements SearchableInterface
  24. {
  25.     /**
  26.      * Index.
  27.      *
  28.      * @var \Elastica\Index Index object
  29.      */
  30.     protected $_index;
  31.     /**
  32.      * Type name.
  33.      *
  34.      * @var string Type name
  35.      */
  36.     protected $_name;
  37.     /**
  38.      * @var array|string A callable that serializes an object passed to it
  39.      */
  40.     protected $_serializer;
  41.     /**
  42.      * Creates a new type object inside the given index.
  43.      *
  44.      * @param \Elastica\Index $index Index Object
  45.      * @param string          $name  Type name
  46.      */
  47.     public function __construct(Index $index$name)
  48.     {
  49.         $this->_index $index;
  50.         $this->_name $name;
  51.     }
  52.     /**
  53.      * Adds the given document to the search index.
  54.      *
  55.      * @param \Elastica\Document $doc Document with data
  56.      *
  57.      * @return \Elastica\Response
  58.      */
  59.     public function addDocument(Document $doc)
  60.     {
  61.         $endpoint = new \Elasticsearch\Endpoints\Index();
  62.         if (null !== $doc->getId() && '' !== $doc->getId()) {
  63.             $endpoint->setID($doc->getId());
  64.         }
  65.         $options $doc->getOptions(
  66.             [
  67.                 'version',
  68.                 'version_type',
  69.                 'routing',
  70.                 'percolate',
  71.                 'parent',
  72.                 'op_type',
  73.                 'consistency',
  74.                 'replication',
  75.                 'refresh',
  76.                 'timeout',
  77.                 'pipeline',
  78.             ]
  79.         );
  80.         $endpoint->setBody($doc->getData());
  81.         $endpoint->setParams($options);
  82.         $response $this->requestEndpoint($endpoint);
  83.         $data $response->getData();
  84.         // set autogenerated id to document
  85.         if (($doc->isAutoPopulate()
  86.                 || $this->getIndex()->getClient()->getConfigValue(['document''autoPopulate'], false))
  87.             && $response->isOk()
  88.         ) {
  89.             if (!$doc->hasId()) {
  90.                 if (isset($data['_id'])) {
  91.                     $doc->setId($data['_id']);
  92.                 }
  93.             }
  94.             if (isset($data['_version'])) {
  95.                 $doc->setVersion($data['_version']);
  96.             }
  97.         }
  98.         return $response;
  99.     }
  100.     /**
  101.      * @param $object
  102.      * @param Document $doc
  103.      *
  104.      * @throws Exception\RuntimeException
  105.      *
  106.      * @return Response
  107.      */
  108.     public function addObject($objectDocument $doc null)
  109.     {
  110.         if (!isset($this->_serializer)) {
  111.             throw new RuntimeException('No serializer defined');
  112.         }
  113.         $data call_user_func($this->_serializer$object);
  114.         if (!$doc) {
  115.             $doc = new Document();
  116.         }
  117.         $doc->setData($data);
  118.         return $this->addDocument($doc);
  119.     }
  120.     /**
  121.      * Update document, using update script. Requires elasticsearch >= 0.19.0.
  122.      *
  123.      * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-update.html
  124.      *
  125.      * @param \Elastica\Document|\Elastica\Script\AbstractScript $data    Document with update data
  126.      * @param array                                              $options array of query params to use for query. For possible options check es api
  127.      *
  128.      * @throws \Elastica\Exception\InvalidException
  129.      *
  130.      * @return \Elastica\Response
  131.      */
  132.     public function updateDocument($data, array $options = [])
  133.     {
  134.         if (!($data instanceof Document) && !($data instanceof AbstractScript)) {
  135.             throw new \InvalidArgumentException('Data should be a Document or Script');
  136.         }
  137.         if (!$data->hasId()) {
  138.             throw new InvalidException('Document or Script id is not set');
  139.         }
  140.         return $this->getIndex()->getClient()->updateDocument(
  141.             $data->getId(),
  142.             $data,
  143.             $this->getIndex()->getName(),
  144.             $this->getName(),
  145.             $options
  146.         );
  147.     }
  148.     /**
  149.      * Uses _bulk to send documents to the server.
  150.      *
  151.      * @param array|\Elastica\Document[] $docs    Array of Elastica\Document
  152.      * @param array                      $options Array of query params to use for query. For possible options check es api
  153.      *
  154.      * @return \Elastica\Bulk\ResponseSet
  155.      *
  156.      * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
  157.      */
  158.     public function updateDocuments(array $docs, array $options = [])
  159.     {
  160.         foreach ($docs as $doc) {
  161.             $doc->setType($this->getName());
  162.         }
  163.         return $this->getIndex()->updateDocuments($docs$options);
  164.     }
  165.     /**
  166.      * Uses _bulk to send documents to the server.
  167.      *
  168.      * @param array|\Elastica\Document[] $docs    Array of Elastica\Document
  169.      * @param array                      $options Array of query params to use for query. For possible options check es api
  170.      *
  171.      * @return \Elastica\Bulk\ResponseSet
  172.      *
  173.      * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
  174.      */
  175.     public function addDocuments(array $docs, array $options = [])
  176.     {
  177.         foreach ($docs as $doc) {
  178.             $doc->setType($this->getName());
  179.         }
  180.         return $this->getIndex()->addDocuments($docs$options);
  181.     }
  182.     /**
  183.      * Uses _bulk to send documents to the server.
  184.      *
  185.      * @param object[] $objects
  186.      * @param array    $options Array of query params to use for query. For possible options check es api
  187.      *
  188.      * @return Bulk\ResponseSet
  189.      *
  190.      * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
  191.      */
  192.     public function addObjects(array $objects, array $options = [])
  193.     {
  194.         if (!isset($this->_serializer)) {
  195.             throw new RuntimeException('No serializer defined');
  196.         }
  197.         $docs = [];
  198.         foreach ($objects as $object) {
  199.             $data call_user_func($this->_serializer$object);
  200.             $doc = new Document();
  201.             $doc->setData($data);
  202.             $doc->setType($this->getName());
  203.             $docs[] = $doc;
  204.         }
  205.         return $this->getIndex()->addDocuments($docs$options);
  206.     }
  207.     /**
  208.      * Get the document from search index.
  209.      *
  210.      * @param string $id      Document id
  211.      * @param array  $options options for the get request
  212.      *
  213.      * @throws \Elastica\Exception\NotFoundException
  214.      * @throws \Elastica\Exception\ResponseException
  215.      *
  216.      * @return \Elastica\Document
  217.      */
  218.     public function getDocument($id$options = [])
  219.     {
  220.         $endpoint = new \Elasticsearch\Endpoints\Get();
  221.         $endpoint->setID($id);
  222.         $endpoint->setParams($options);
  223.         $response $this->requestEndpoint($endpoint);
  224.         $result $response->getData();
  225.         if (!isset($result['found']) || false === $result['found']) {
  226.             throw new NotFoundException('doc id '.$id.' not found');
  227.         }
  228.         if (isset($result['fields'])) {
  229.             $data $result['fields'];
  230.         } elseif (isset($result['_source'])) {
  231.             $data $result['_source'];
  232.         } else {
  233.             $data = [];
  234.         }
  235.         $document = new Document($id$data$this->getName(), $this->getIndex());
  236.         $document->setVersion($result['_version']);
  237.         return $document;
  238.     }
  239.     /**
  240.      * @param string       $id
  241.      * @param array|string $data
  242.      *
  243.      * @return Document
  244.      */
  245.     public function createDocument($id ''$data = [])
  246.     {
  247.         $document = new Document($id$data);
  248.         $document->setType($this);
  249.         return $document;
  250.     }
  251.     /**
  252.      * Returns the type name.
  253.      *
  254.      * @return string Type name
  255.      */
  256.     public function getName()
  257.     {
  258.         return $this->_name;
  259.     }
  260.     /**
  261.      * Sets value type mapping for this type.
  262.      *
  263.      * @param \Elastica\Type\Mapping|array $mapping Elastica\Type\MappingType object or property array with all mappings
  264.      * @param array                        $query   querystring when put mapping (for example update_all_types)
  265.      *
  266.      * @return \Elastica\Response
  267.      */
  268.     public function setMapping($mapping, array $query = [])
  269.     {
  270.         $mapping Mapping::create($mapping);
  271.         $mapping->setType($this);
  272.         return $mapping->send($query);
  273.     }
  274.     /**
  275.      * Returns current mapping for the given type.
  276.      *
  277.      * @return array Current mapping
  278.      */
  279.     public function getMapping()
  280.     {
  281.         $response $this->requestEndpoint(new Get());
  282.         $data $response->getData();
  283.         $mapping array_shift($data);
  284.         if (isset($mapping['mappings'])) {
  285.             return $mapping['mappings'];
  286.         }
  287.         return [];
  288.     }
  289.     /**
  290.      * Create search object.
  291.      *
  292.      * @param string|array|\Elastica\Query $query   Array with all query data inside or a Elastica\Query object
  293.      * @param int|array                    $options OPTIONAL Limit or associative array of options (option=>value)
  294.      * @param BuilderInterface             $builder
  295.      *
  296.      * @return Search
  297.      */
  298.     public function createSearch($query ''$options nullBuilderInterface $builder null)
  299.     {
  300.         $search $this->getIndex()->createSearch($query$options$builder);
  301.         $search->addType($this);
  302.         return $search;
  303.     }
  304.     /**
  305.      * Do a search on this type.
  306.      *
  307.      * @param string|array|\Elastica\Query $query   Array with all query data inside or a Elastica\Query object
  308.      * @param int|array                    $options OPTIONAL Limit or associative array of options (option=>value)
  309.      *
  310.      * @return \Elastica\ResultSet with all results inside
  311.      *
  312.      * @see \Elastica\SearchableInterface::search
  313.      */
  314.     public function search($query ''$options null)
  315.     {
  316.         $search $this->createSearch($query$options);
  317.         return $search->search();
  318.     }
  319.     /**
  320.      * Count docs by query.
  321.      *
  322.      * @param string|array|\Elastica\Query $query Array with all query data inside or a Elastica\Query object
  323.      *
  324.      * @return int number of documents matching the query
  325.      *
  326.      * @see \Elastica\SearchableInterface::count
  327.      */
  328.     public function count($query '')
  329.     {
  330.         $search $this->createSearch($query);
  331.         return $search->count();
  332.     }
  333.     /**
  334.      * Returns index client.
  335.      *
  336.      * @return \Elastica\Index Index object
  337.      */
  338.     public function getIndex()
  339.     {
  340.         return $this->_index;
  341.     }
  342.     /**
  343.      * @param \Elastica\Document $document
  344.      *
  345.      * @return \Elastica\Response
  346.      */
  347.     public function deleteDocument(Document $document)
  348.     {
  349.         $options $document->getOptions(
  350.             [
  351.                 'version',
  352.                 'version_type',
  353.                 'routing',
  354.                 'parent',
  355.                 'replication',
  356.                 'consistency',
  357.                 'refresh',
  358.                 'timeout',
  359.             ]
  360.         );
  361.         return $this->deleteById($document->getId(), $options);
  362.     }
  363.     /**
  364.      * Uses _bulk to delete documents from the server.
  365.      *
  366.      * @param array|\Elastica\Document[] $docs Array of Elastica\Document
  367.      *
  368.      * @return \Elastica\Bulk\ResponseSet
  369.      *
  370.      * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html
  371.      */
  372.     public function deleteDocuments(array $docs)
  373.     {
  374.         foreach ($docs as $doc) {
  375.             $doc->setType($this->getName());
  376.         }
  377.         return $this->getIndex()->deleteDocuments($docs);
  378.     }
  379.     /**
  380.      * Deletes an entry by its unique identifier.
  381.      *
  382.      * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete.html
  383.      *
  384.      * @param int|string $id      Document id
  385.      * @param array      $options
  386.      *
  387.      * @throws \InvalidArgumentException
  388.      * @throws \Elastica\Exception\NotFoundException
  389.      *
  390.      * @return \Elastica\Response Response object
  391.      */
  392.     public function deleteById($id, array $options = [])
  393.     {
  394.         if (empty($id) || !trim($id)) {
  395.             throw new \InvalidArgumentException();
  396.         }
  397.         $endpoint = new Delete();
  398.         $endpoint->setID($id);
  399.         $endpoint->setParams($options);
  400.         $response $this->requestEndpoint($endpoint);
  401.         $responseData $response->getData();
  402.         if (isset($responseData['result']) && 'not_found' == $responseData['result']) {
  403.             throw new NotFoundException('Doc id '.$id.' not found and can not be deleted');
  404.         }
  405.         return $response;
  406.     }
  407.     /**
  408.      * Deletes the given list of ids from this type.
  409.      *
  410.      * @param array       $ids
  411.      * @param string|bool $routing Optional routing key for all ids
  412.      *
  413.      * @return \Elastica\Response Response  object
  414.      */
  415.     public function deleteIds(array $ids$routing false)
  416.     {
  417.         return $this->getIndex()->getClient()->deleteIds($ids$this->getIndex(), $this$routing);
  418.     }
  419.     /**
  420.      * Deletes entries in the db based on a query.
  421.      *
  422.      * @param \Elastica\Query|\Elastica\Query\AbstractQuery|string|array $query   Query object
  423.      * @param array                                                      $options Optional params
  424.      *
  425.      * @return \Elastica\Response
  426.      *
  427.      * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-delete-by-query.html
  428.      */
  429.     public function deleteByQuery($query, array $options = [])
  430.     {
  431.         $query Query::create($query);
  432.         $endpoint = new DeleteByQuery();
  433.         $endpoint->setBody($query->toArray());
  434.         $endpoint->setParams($options);
  435.         return $this->requestEndpoint($endpoint);
  436.     }
  437.     /**
  438.      * Makes calls to the elasticsearch server based on this type.
  439.      *
  440.      * @param string $path   Path to call
  441.      * @param string $method Rest method to use (GET, POST, DELETE, PUT)
  442.      * @param array  $data   OPTIONAL Arguments as array
  443.      * @param array  $query  OPTIONAL Query params
  444.      *
  445.      * @return \Elastica\Response Response object
  446.      */
  447.     public function request($path$method$data = [], array $query = [])
  448.     {
  449.         $path $this->getName().'/'.$path;
  450.         return $this->getIndex()->request($path$method$data$query);
  451.     }
  452.     /**
  453.      * Makes calls to the elasticsearch server with usage official client Endpoint based on this type.
  454.      *
  455.      * @param AbstractEndpoint $endpoint
  456.      *
  457.      * @return Response
  458.      */
  459.     public function requestEndpoint(AbstractEndpoint $endpoint)
  460.     {
  461.         $cloned = clone $endpoint;
  462.         $cloned->setType($this->getName());
  463.         return $this->getIndex()->requestEndpoint($cloned);
  464.     }
  465.     /**
  466.      * Sets the serializer callable used in addObject.
  467.      *
  468.      * @see \Elastica\Type::addObject
  469.      *
  470.      * @param array|string $serializer @see \Elastica\Type::_serializer
  471.      *
  472.      * @return $this
  473.      */
  474.     public function setSerializer($serializer)
  475.     {
  476.         $this->_serializer $serializer;
  477.         return $this;
  478.     }
  479.     /**
  480.      * Checks if the given type exists in Index.
  481.      *
  482.      * @return bool True if type exists
  483.      */
  484.     public function exists()
  485.     {
  486.         $response $this->requestEndpoint(new Exists());
  487.         return 200 === $response->getStatus();
  488.     }
  489. }