Skip to content

FIX for issue 9930 - Asymmetric Transaction Error with ElasticSearch #10610

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

Merged
merged 1 commit into from
Aug 23, 2017
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ public function addImage(
$mediaGalleryData['images'][] = [
'file' => $fileName,
'position' => $position,
'media_type' => 'image',
Copy link
Contributor

@maghamed maghamed Aug 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @phoenix128 , This PR makes sense for Magento 2.1.x , because in Magento 2.2.0
We've deprecated interface

namespace Magento\Elasticsearch\Model\Adapter;

/**
 * @deprecated
 * @see \Magento\Elasticsearch\Model\Adapter\BatchDataMapperInterface
 */
interface DataMapperInterface

and added \Magento\Elasticsearch\Model\Adapter\BatchDataMapperInterface instead.
In the implementation of new ProductDataMapper we don't support handling and persisting Media attribute types and adding them to ES index.

namespace Magento\Elasticsearch\Model\Adapter\BatchDataMapper;

/**
 * Map product index data to search engine metadata
 */
class ProductDataMapper implements BatchDataMapperInterface
{
    /**
     * List of attributes which will be skipped during mapping
     *
     * @var array
     */
    private $defaultExcludedAttributes = [
        'price',
        'media_gallery',
        'tier_price',
        'quantity_and_stock_status',
        'media_gallery',
        'giftcard_amounts',
    ];


    /**
     * {@inheritdoc}
     */
    public function map(array $documentData, $storeId, array $context = [])
    {
        // reset attribute data for new store
        $this->attributeData = [];
        $documents = [];

        foreach ($documentData as $productId => $indexData) {
            $this->builder->addField('store_id', $storeId);
            $productIndexData = $this->convertToProductData($productId, $indexData, $storeId);
            foreach ($productIndexData as $attributeCode => $value) {
                if (in_array($attributeCode, $this->excludedAttributes, true)) {
                    continue;
                }
                $this->builder->addField(
                    $this->fieldMapper->getFieldName(
                        $attributeCode,
                        $context
                    ),
                    $value
                );
            }
            $documents[$productId] = $this->builder->build();
        }

Regarding PR in 2.1.x - I propose to slightly modify ProductDataMapper along with your change as well, because the real root cause of the problem is Magento\Elasticsearch\Model\Adapter\DataMapper\ProductDataMapper

    protected function getProductMediaGalleryData($media, $roles)
    {
        $result = [];

        if (!empty($media['images'])) {
            $i = 0;
            foreach ($media['images'] as $data) {
                if ($data['media_type'] === 'image') {
                    $result['image_file_' . $i] = $data['file'];
                    $result['image_position_' . $i] = $data['position'];
                    $result['image_disabled_' . $i] = $data['disabled'];
                    $result['image_label_' . $i] = $data['label'];
                    $result['image_title_' . $i] = $data['label'];
                    $result['image_base_image_' . $i] = $this->getMediaRoleImage($data['file'], $roles);
                    $result['image_small_image_' . $i] = $this->getMediaRoleSmallImage($data['file'], $roles);
                    $result['image_thumbnail_' . $i] = $this->getMediaRoleThumbnail($data['file'], $roles);
                    $result['image_swatch_image_' . $i] = $this->getMediaRoleSwatchImage($data['file'], $roles);
                } else {
                    $result['video_file_' . $i] = $data['file'];
                    $result['video_position_' . $i] = $data['position'];
                    $result['video_disabled_' . $i] = $data['disabled'];
                    $result['video_label_' . $i] = $data['label'];
                    $result['video_title_' . $i] = $data['video_title'];
                    $result['video_base_image_' . $i] = $this->getMediaRoleImage($data['file'], $roles);
                    $result['video_small_image_' . $i] = $this->getMediaRoleSmallImage($data['file'], $roles);
                    $result['video_thumbnail_' . $i] = $this->getMediaRoleThumbnail($data['file'], $roles);
                    $result['video_swatch_image_' . $i] = $this->getMediaRoleSwatchImage($data['file'], $roles);
                    $result['video_url_' . $i] = $data['video_url'];
                    $result['video_description_' . $i] = $data['video_description'];
                    $result['video_metadata_' . $i] = $data['video_metadata'];
                    $result['video_provider_' . $i] = $data['video_provider'];
                }
                $i++;
            }
        }
        return $result;
    }

Currently there are two types of media content in Magento :
external-video and image
I propose to add next code to the above function:

                if ($data['media_type'] === 'image') {
                    // some logic here
                } elseif ($data['media_type'] === 'external-video') {
                    // some logic here
                } else {
              throw new Magento\Framework\Exception\InputExcaption('Unsupported Media Type Provided');
                }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maghamed I don't know where the source code is for the elastic search stuff, but since the defaultExcludedAttributes are private, is there a way to change them or override them? I want to include price and media gallery, but since its private and not protected, I don't know a way around this.

'label' => '',
'disabled' => (int)$exclude,
];
Expand Down