IndexerHandler.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\CatalogSearch\Model\Indexer;
  7. use Magento\Eav\Model\Config;
  8. use Magento\Framework\App\ResourceConnection;
  9. use Magento\Framework\Indexer\SaveHandler\IndexerInterface;
  10. use Magento\Framework\Indexer\IndexStructureInterface;
  11. use Magento\Framework\Search\Request\Dimension;
  12. use Magento\Framework\Search\Request\IndexScopeResolverInterface;
  13. use Magento\Framework\Indexer\SaveHandler\Batch;
  14. /**
  15. * Catalog search indexer handler.
  16. *
  17. * @api
  18. * @since 100.0.2
  19. * @deprecated 101.0.0
  20. * @see \Magento\ElasticSearch
  21. */
  22. class IndexerHandler implements IndexerInterface
  23. {
  24. /**
  25. * @var IndexStructureInterface
  26. */
  27. private $indexStructure;
  28. /**
  29. * @var array
  30. */
  31. private $data;
  32. /**
  33. * @var array
  34. */
  35. private $fields;
  36. /**
  37. * @var Resource|Resource
  38. */
  39. private $resource;
  40. /**
  41. * @var Batch
  42. */
  43. private $batch;
  44. /**
  45. * @var Config
  46. */
  47. private $eavConfig;
  48. /**
  49. * @var int
  50. */
  51. private $batchSize;
  52. /**
  53. * @var IndexScopeResolverInterface
  54. */
  55. private $indexScopeResolver;
  56. /**
  57. * @param IndexStructureInterface $indexStructure
  58. * @param ResourceConnection $resource
  59. * @param Config $eavConfig
  60. * @param Batch $batch
  61. * @param IndexScopeResolverInterface $indexScopeResolver
  62. * @param array $data
  63. * @param int $batchSize
  64. */
  65. public function __construct(
  66. IndexStructureInterface $indexStructure,
  67. ResourceConnection $resource,
  68. Config $eavConfig,
  69. Batch $batch,
  70. IndexScopeResolverInterface $indexScopeResolver,
  71. array $data,
  72. $batchSize = 500
  73. ) {
  74. $this->indexScopeResolver = $indexScopeResolver;
  75. $this->indexStructure = $indexStructure;
  76. $this->resource = $resource;
  77. $this->batch = $batch;
  78. $this->eavConfig = $eavConfig;
  79. $this->data = $data;
  80. $this->fields = [];
  81. $this->prepareFields();
  82. $this->batchSize = $batchSize;
  83. }
  84. /**
  85. * @inheritdoc
  86. */
  87. public function saveIndex($dimensions, \Traversable $documents)
  88. {
  89. foreach ($this->batch->getItems($documents, $this->batchSize) as $batchDocuments) {
  90. $this->insertDocuments($batchDocuments, $dimensions);
  91. }
  92. }
  93. /**
  94. * @inheritdoc
  95. */
  96. public function deleteIndex($dimensions, \Traversable $documents)
  97. {
  98. foreach ($this->batch->getItems($documents, $this->batchSize) as $batchDocuments) {
  99. $this->resource->getConnection()
  100. ->delete($this->getTableName($dimensions), ['entity_id in (?)' => $batchDocuments]);
  101. }
  102. }
  103. /**
  104. * @inheritdoc
  105. */
  106. public function cleanIndex($dimensions)
  107. {
  108. $this->indexStructure->delete($this->getIndexName(), $dimensions);
  109. $this->indexStructure->create($this->getIndexName(), [], $dimensions);
  110. }
  111. /**
  112. * @inheritdoc
  113. */
  114. public function isAvailable($dimensions = [])
  115. {
  116. if (empty($dimensions)) {
  117. return true;
  118. }
  119. return $this->resource->getConnection()->isTableExists($this->getTableName($dimensions));
  120. }
  121. /**
  122. * Returns table name.
  123. *
  124. * @param Dimension[] $dimensions
  125. * @return string
  126. */
  127. private function getTableName($dimensions)
  128. {
  129. return $this->indexScopeResolver->resolve($this->getIndexName(), $dimensions);
  130. }
  131. /**
  132. * Returns index name.
  133. *
  134. * @return string
  135. */
  136. private function getIndexName()
  137. {
  138. return $this->data['indexer_id'];
  139. }
  140. /**
  141. * Add documents to storage.
  142. *
  143. * @param array $documents
  144. * @param Dimension[] $dimensions
  145. * @return void
  146. */
  147. private function insertDocuments(array $documents, array $dimensions)
  148. {
  149. $documents = $this->prepareSearchableFields($documents);
  150. if (empty($documents)) {
  151. return;
  152. }
  153. $this->resource->getConnection()->insertOnDuplicate(
  154. $this->getTableName($dimensions),
  155. $documents,
  156. ['data_index']
  157. );
  158. }
  159. /**
  160. * Searchable filter preparation.
  161. *
  162. * @param array $documents
  163. * @return array
  164. */
  165. private function prepareSearchableFields(array $documents)
  166. {
  167. $insertDocuments = [];
  168. foreach ($documents as $entityId => $document) {
  169. foreach ($document as $attributeId => $fieldValue) {
  170. $insertDocuments[$entityId . '_' . $attributeId] = [
  171. 'entity_id' => $entityId,
  172. 'attribute_id' => $attributeId,
  173. 'data_index' => $fieldValue,
  174. ];
  175. }
  176. }
  177. return $insertDocuments;
  178. }
  179. /**
  180. * Prepare fields.
  181. *
  182. * @return void
  183. */
  184. private function prepareFields()
  185. {
  186. foreach ($this->data['fieldsets'] as $fieldset) {
  187. $this->fields = array_merge($this->fields, $fieldset['fields']);
  188. }
  189. }
  190. }