Bảng Magento core_url_rewrite quá lớn


105

Tôi đã nhận thấy một số lượng lớn các báo cáo rằng chính bảng này có thể trở nên cực kỳ lộn xộn, tôi đang điều hành một trang web với ~ 5000 SKU và ~ 250 danh mục (một cửa hàng) và một core_url_rewritebảng kết quả gồm hơn 600.000 dòng và lớn hơn 500 MB là điên rồ.

Điều này có thể làm chậm hiệu suất trang web và dẫn đến một cơ sở dữ liệu rất cồng kềnh. Tôi đã thực hiện một số hoạt động đào và tìm thấy khá nhiều bài viết liên quan đến điều này, đáng chú ý nhất là:

// Các liên kết này đã bị xóa kể từ khi triển khai các bảng mới

Bây giờ tôi hiểu rằng bảng có thể được cắt ngắn và lập lại, nhưng điều này không giải quyết được vấn đề, nó chỉ kéo dài vấn đề xảy ra lần nữa.

Theo những gì tôi hiểu, một phần của vấn đề là các sản phẩm có cùng khóa url dựa trên tên của sản phẩm, do đó dẫn đến các liên kết được lập chỉ mục.

Một sửa chữa được đề cập là:

app/code/core/Mage/Catalog/Model/Url.php trên dòng ~ 807:

Thay đổi:

 if ($product->getUrlKey() == '' && !empty($requestPath)
       && strpos($existingRequestPath, $requestPath) === 0
 ) 

Đến:

 if (!empty($requestPath)
       && strpos($existingRequestPath, $requestPath) === 0
 ) 

Nhưng ngay cả điều này không hoàn toàn giải quyết vấn đề.

Câu hỏi của tôi như sau:

Nếu bạn đã gặp phải vấn đề này, bạn đã quản lý để thiết lập một thuật toán hiệu quả, hợp lý và hiệu quả không liên quan đến việc "quản lý" vấn đề nhiều lần, nhưng thực sự giải quyết vấn đề một lần và mãi mãi?

Sẽ thực sự đánh giá cao một số cái nhìn sâu sắc về điều này.

BTW: Vui lòng tạo cho mình một ưu tiên và kiểm tra xem bảng của bạn trông như thế nào ngay bây giờ, bạn có thể gặp phải vấn đề này và ảnh hưởng đến hiệu suất do đó mà không hề biết - tôi đã không làm vậy.

Chỉnh sửa: Tôi đã liên hệ với www.Nexcess.net (một đối tác lưu trữ bạch kim Magento) và họ đã xác nhận rằng họ đã có khách hàng yêu cầu core_url_rewritebảng của họ yêu cầu cắt bớt do quá cồng kềnh.

Một lo lắng lớn của tôi là tác động SEO mà điều này có thể có, đó là lý do tại sao tôi muốn một giải pháp thay vì trì hoãn vấn đề phát sinh lại.

Cập nhật: Nexcess đã đề cập rằng với các sản phẩm trùng lặp trong bảng, nó thực sự có thể gây tổn hại cho SEO.


Wow, đó là một cái bàn lớn đáng kinh ngạc. Tôi đã tự kiểm tra (200 sản phẩm) và nó chỉ có ~ 800 hàng, nhưng chúng tôi không gặp vấn đề gì khi sao chép tên / URL sản phẩm. Là một điểm tham chiếu, chúng tôi có khoảng 6,6 hàng cho mỗi sản phẩm có thể nhìn thấy. Tôi sẽ thừa nhận đây không phải là một so sánh thực tế khủng khiếp, nhưng với tốc độ đó, với 5.000 sản phẩm chúng tôi chỉ có ~ 30.000 hàng hoặc hơn. Tôi cũng có thể hiểu nhu cầu của bạn về một giải pháp và sẽ xem câu hỏi này khi tôi sắp triển khai một trang web lớn hơn nhiều.
Pete855217

@ Pete855217: câu hỏi này nghe có vẻ thú vị mặc dù bạn chưa nêu ra.
Mohammad Faisal

1
Có một lỗi trong EE1.12 khiến cho việc ghi lại được tạo lại trên mỗi lần lưu. Có thể phiên bản 1.7 của bạn có lỗi tương tự. Khi tôi nhớ lại bản vá cho 1.12 cũng hoạt động vào ngày 1.7
brentwpeterson

1
Bài viết rất hữu ích! Chúng tôi có 130.000 sản phẩm đang hoạt động và 25.000 sản phẩm bị vô hiệu hóa, core_url_rewrite_table của chúng tôi có 2744023 hồ sơ trong đó ..... vì vậy tuần này chúng tôi sẽ bắt tay vào khắc phục điều này !! Bài viết này có vẻ là một điểm khởi đầu tốt.
MagentoMac

Đã chỉnh sửa bài đăng để bao gồm cách không xóa các bài viết tùy chỉnh của bạn trong Magento.
Espradley

Câu trả lời:


76

Tôi đã cố gắng khắc phục vấn đề như sau:

Bước 1: Viết lại mô hình URL Danh mục (Sử dụng mô-đun của riêng bạn: Cách thực hiện )

Lưu ý: Nếu bạn ghi đè lên tệp lõi mà không sử dụng ghi lại, điều này sẽ khiến phiên bản Magento của bạn không có khả năng nâng cấp trong tương lai.

Theo giải pháp của Jahnni trên bảng thương mại Magento(không còn hoạt động với bảng mới), app/code/core/Mage/Catalog/Model/Url.php[khoảng dòng 807 Mage_Catalog_Model_Url::getProductRequestPath()]

Từ:

if ($product->getUrlKey() == '' && !empty($requestPath)
   && strpos($existingRequestPath, $requestPath) === 0
) 

Đến:

if (!empty($requestPath)
           && strpos($existingRequestPath, $requestPath) === 0
) 

Bước 2: Cắt ngắn

Cắt core_url_rewritebàn

Bước 3: Reindex & Flush Caches

Bắt đầu quá trình lập chỉ mục lại trên các phần thưởng URL cốt lõi. Sau đó, bạn sẽ muốn xóa bộ nhớ cache & bộ nhớ cache Magento.

SystemCache ManagementFlush Magento Cache

SystemCache ManagementFlush Cache Storage

Voila, bạn đã sẵn sàng. Bạn sẽ nhận thấy nếu bạn chạy lại bộ chỉ mục, bảng sẽ giữ nguyên kích thước (trừ khi bạn đã thêm nhiều sản phẩm ở giữa hoặc nếu bạn có tên danh mục trùng lặp).


5
Tuyệt vời, bảng core_url_rewrite của tôi là 3,2 GB hiện tại là 36,8 MB: D bởi muppet
Fabian Blechschmidt

Tôi có một vấn đề tương tự. Magento URL viết lại nối số ngẫu nhiên trong Url. Vui lòng nhìn vào ảnh chụp màn hình đính kèm từ google web master tools. Như bạn có thể thấy sản phẩm "Saree Wedding Wedding Saree" có chín URL khác nhau nhưng nó chỉ là một sản phẩm và chỉ trỏ đến một URL kết thúc bằng 878. Khóa URL thực tế không có số ngẫu nhiên ở cuối (đính kèm ảnh chụp màn hình ). Cửa hàng của tôi khá mới và kích thước của core_url_rewrite không lớn. Vì vậy, tôi không chắc chắn liệu tôi có nên tiếp tục và thực hiện Bước 1 & 2 hay Chỉ Bước 1. Nếu tôi thực hiện bước 2, tôi sẽ mất các bản viết lại tùy chỉnh của mình.
Zoya

Tôi đang chạy 1.9.1 và đây là các url ảnh chụp màn hình. monosnap.com/image/duL0f64WWlACtlt9kcn04BWqY3L5Xl monosnap.com/image/osFk8kYNAr00XLdFTGTIOaydaW5yqS
Zoya

2
Tôi sẽ xuất bảng hiện có trước. Sau đó, tôi sẽ tiến hành các bước 1, 2 và 3. Hãy xem core_url_rewritebảng bây giờ và ghi lại số lượng hồ sơ. Chạy lại bước 3 (lập chỉ mục lại) và làm mới chế độ xem của bạn trên core_url_rewritebảng. Nếu số lượng giống nhau, bạn đã giải quyết thành công. Sau đó, tiếp tục và hợp nhất thủ công viết lại tùy chỉnh của bạn. Tất cả tốt nhất.
Moose

2
Khắc phục sự cố này chỉ hoạt động cho các sản phẩm, không dành cho các danh mục có khóa URL giống hệt nhau. Xem câu trả lời của @Simon để có giải pháp tốt hơn (với tệp vá)
Giel Berkers

45

Trong khi tôi hy vọng ai đó ở đây đưa ra câu trả lời, tôi không biết rằng bạn sẽ tìm thấy câu trả lời. Bảng này trở nên cồng kềnh vì nhiều lý do khác nhau. Lỗi trong các phiên bản trước đó (và có thể là hiện tại) của Magento là một. Một cái khác là có logic trong bảng này cố gắng theo dõi các thay đổi đối với giá trị khóa URL để viết lại 301/302 cho các sản phẩm cũ. Bởi vì điều này và làm phức tạp mọi thứ, việc cắt bớt bảng và tạo lại có thể làm cho các ghi lại URL hiện tại biến mất và điều này sẽ có ảnh hưởng không xác định đến danh sách công cụ tìm kiếm của bạn (không nhất thiết là xấu, chỉ khó dự đoán).

Lời khuyên chung của tôi cho khách hàng hỏi là

  1. Rời khỏi bảng phát triển khổng lồ như thể bạn không xử lý tốt tình huống URL / SEO của mình

  2. Cho đến khi kích thước bảng bắt đầu là một vấn đề (ví dụ: tạo bản đồ trang web). Khi điều đó xảy ra, hãy xử lý tình huống URL / SEO của bạn.

  3. Khi bạn đã xử lý tình huống URL / SEO của mình, hãy sao lưu bảng, sau đó cắt bớt bảng và tạo lại. Giải quyết bất kỳ vấn đề URL / SEO gây ra bởi việc cắt ngắn.

  4. Tự động hóa bước 3

Cố gắng khắc phục điều này ở cấp mã Magento là đáng ngưỡng mộ, nhưng bạn sẽ bơi ngược dòng. Đôi khi, tốt hơn hết là chấp nhận rằng "Đó chỉ là Magento là Magento", và để giải quyết vấn đề với quá trình bên ngoài.


cảm ơn vì lời khuyên, thật đáng tiếc về tình huống này nhưng tôi nghĩ rằng nó sẽ phải được xử lý bởi một quy trình bên ngoài như bạn đã đề cập, urgh.
Moose

2
Bảng khổng lồ này đã có thể gây ra các vấn đề SEO, vì kinh điển cho một sản phẩm nhất định sẽ thay đổi liên tục. Nếu bạn có một kho lưu trữ riêng cho thiết bị di động và máy tính để bàn, thì điều đó còn tồi tệ hơn vì URL của chúng sẽ khác nhau.
Melvyn

Một câu trả lời hơi thất vọng với tôi ...
Fra

@Alan Storm, bạn cảm thấy thế nào về câu trả lời được đăng bởi Moose sau khi bạn đăng câu trả lời này? Bạn có thấy những rủi ro tương tự?
Ngỗng

24

Tôi muốn thêm một bản sửa lỗi cho lỗi chỉ mục viết lại url này đã được phát triển tại bugathon vào tháng 3 năm 2013 và đã được cải thiện hơn nữa sau đó. Nó sẽ giải quyết vấn đề này. Để tham khảo, đây là tệp vá từ liên kết:

diff -rupN mage_org/app/code/core/Mage/Catalog/Model/Url.php src_shop/app/code/core/Mage/Catalog/Model/Url.php
--- mage_org/app/code/core/Mage/Catalog/Model/Url.php   2013-11-19 00:48:25.679009391 +0100
+++ src_shop/app/code/core/Mage/Catalog/Model/Url.php   2013-11-19 00:49:24.188005601 +0100
@@ -643,13 +643,24 @@ class Mage_Catalog_Model_Url
                 $this->_rewrite = $rewrite;
                 return $requestPath;
             }
+
+            // avoid unnecessary creation of new url_keys for duplicate url keys
+            $noSuffixPath = substr($requestPath, 0, -(strlen($suffix)));
+            $regEx = '#^('.preg_quote($noSuffixPath).')(-([0-9]+))?('.preg_quote($suffix).')#i';
+            $currentRewrite = $this->getResource()->getRewriteByIdPath($idPath, $storeId);
+            if ($currentRewrite && preg_match($regEx, $currentRewrite->getRequestPath(), $match)) {
+                $this->_rewrite = $currentRewrite;
+                return $currentRewrite->getRequestPath();
+            }
+
             // match request_url abcdef1234(-12)(.html) pattern
             $match = array();
             $regularExpression = '#^([0-9a-z/-]+?)(-([0-9]+))?('.preg_quote($suffix).')?$#i';
             if (!preg_match($regularExpression, $requestPath, $match)) {
                 return $this->getUnusedPath($storeId, '-', $idPath);
             }
-            $match[1] = $match[1] . '-';
+            $match[1] = $noSuffixPath . '-'; // always use full prefix of url_key
+            unset($match[3]); // don't start counting with a possible number in the url_key
             $match[4] = isset($match[4]) ? $match[4] : '';

             $lastRequestPath = $this->getResource()


Ngoài ra, tôi muốn thêm bản vá EE PATCH_SUPEE-389_EE_1.12.0.2_v2.sh, hiện có sẵn trên GitHub :

#!/bin/bash
# Patch apllying tool template
# v0.1.2
# (c) Copyright 2013. Magento Inc.
#
# DO NOT CHANGE ANY LINE IN THIS FILE.

# 1. Check required system tools
_check_installed_tools() {
    local missed=""

    until [ -z "$1" ]; do
        type -t $1 >/dev/null 2>/dev/null
        if (( $? != 0 )); then
            missed="$missed $1"
        fi
        shift
    done

    echo $missed
}

REQUIRED_UTILS='sed patch'
MISSED_REQUIRED_TOOLS=`_check_installed_tools $REQUIRED_UTILS`
if (( `echo $MISSED_REQUIRED_TOOLS | wc -w` > 0 ));
then
    echo -e "Error! Some required system tools, that are utilized in this sh script, are not installed:\nTool(s) \"$MISSED_REQUIRED_TOOLS\" is(are) missed, please install it(them)."
    exit 1
fi

# 2. Determine bin path for system tools
CAT_BIN=`which cat`
PATCH_BIN=`which patch`
SED_BIN=`which sed`
PWD_BIN=`which pwd`
BASENAME_BIN=`which basename`

BASE_NAME=`$BASENAME_BIN "$0"`

# 3. Help menu
if [ "$1" = "-?" -o "$1" = "-h" -o "$1" = "--help" ]
then
    $CAT_BIN << EOFH
Usage: sh $BASE_NAME [--help] [-R|--revert] [--list]
Apply embedded patch.

-R, --revert    Revert previously applied embedded patch
--list          Show list of applied patches
--help          Show this help message
EOFH
    exit 0
fi

# 4. Get "revert" flag and "list applied patches" flag
REVERT_FLAG=
SHOW_APPLIED_LIST=0
if [ "$1" = "-R" -o "$1" = "--revert" ]
then
    REVERT_FLAG=-R
fi
if [ "$1" = "--list" ]
then
    SHOW_APPLIED_LIST=1
fi

# 5. File pathes
CURRENT_DIR=`$PWD_BIN`/
APP_ETC_DIR=`echo "$CURRENT_DIR""app/etc/"`
APPLIED_PATCHES_LIST_FILE=`echo "$APP_ETC_DIR""applied.patches.list"`

# 6. Show applied patches list if requested
if [ "$SHOW_APPLIED_LIST" -eq 1 ] ; then
    echo -e "Applied/reverted patches list:"
    if [ -e "$APPLIED_PATCHES_LIST_FILE" ]
    then
        if [ ! -r "$APPLIED_PATCHES_LIST_FILE" ]
        then
            echo "ERROR: \"$APPLIED_PATCHES_LIST_FILE\" must be readable so applied patches list can be shown."
            exit 1
        else
            $SED_BIN -n "/SUP-\|SUPEE-/p" $APPLIED_PATCHES_LIST_FILE
        fi
    else
        echo "<empty>"
    fi
    exit 0
fi

# 7. Check applied patches track file and its directory
_check_files() {
    if [ ! -e "$APP_ETC_DIR" ]
    then
        echo "ERROR: \"$APP_ETC_DIR\" must exist for proper tool work."
        exit 1
    fi

    if [ ! -w "$APP_ETC_DIR" ]
    then
        echo "ERROR: \"$APP_ETC_DIR\" must be writeable for proper tool work."
        exit 1
    fi

    if [ -e "$APPLIED_PATCHES_LIST_FILE" ]
    then
        if [ ! -w "$APPLIED_PATCHES_LIST_FILE" ]
        then
            echo "ERROR: \"$APPLIED_PATCHES_LIST_FILE\" must be writeable for proper tool work."
            exit 1
        fi
    fi
}

_check_files

# 8. Apply/revert patch
# Note: there is no need to check files permissions for files to be patched.
# "patch" tool will not modify any file if there is not enough permissions for all files to be modified.
# Get start points for additional information and patch data
SKIP_LINES=$((`$SED_BIN -n "/^__PATCHFILE_FOLLOWS__$/=" "$CURRENT_DIR""$BASE_NAME"` + 1))
ADDITIONAL_INFO_LINE=$(($SKIP_LINES - 3))p

_apply_revert_patch() {
    DRY_RUN_FLAG=
    if [ "$1" = "dry-run" ]
    then
        DRY_RUN_FLAG=" --dry-run"
        echo "Checking if patch can be applied/reverted successfully..."
    fi
    PATCH_APPLY_REVERT_RESULT=`$SED_BIN -e '1,/^__PATCHFILE_FOLLOWS__$/d' "$CURRENT_DIR""$BASE_NAME" | $PATCH_BIN $DRY_RUN_FLAG $REVERT_FLAG -p0`
    PATCH_APPLY_REVERT_STATUS=$?
    if [ $PATCH_APPLY_REVERT_STATUS -eq 1 ] ; then
        echo -e "ERROR: Patch can't be applied/reverted successfully.\n\n$PATCH_APPLY_REVERT_RESULT"
        exit 1
    fi
    if [ $PATCH_APPLY_REVERT_STATUS -eq 2 ] ; then
        echo -e "ERROR: Patch can't be applied/reverted successfully."
        exit 2
    fi
}

REVERTED_PATCH_MARK=
if [ -n "$REVERT_FLAG" ]
then
    REVERTED_PATCH_MARK=" | REVERTED"
fi

_apply_revert_patch dry-run
_apply_revert_patch

# 9. Track patch applying result
echo "Patch was applied/reverted successfully."
ADDITIONAL_INFO=`$SED_BIN -n ""$ADDITIONAL_INFO_LINE"" "$CURRENT_DIR""$BASE_NAME"`
APPLIED_REVERTED_ON_DATE=`date -u +"%F %T UTC"`
APPLIED_REVERTED_PATCH_INFO=`echo -n "$APPLIED_REVERTED_ON_DATE"" | ""$ADDITIONAL_INFO""$REVERTED_PATCH_MARK"`
echo -e "$APPLIED_REVERTED_PATCH_INFO\n$PATCH_APPLY_REVERT_RESULT\n\n" >> "$APPLIED_PATCHES_LIST_FILE"

exit 0


SUPEE-389 | EE_1.12.0.2 | v1 | 53c8ca52583358953b143aaa1a78cf409e8dd846 | Thu Jun 20 10:36:39 2013 +0300 | v1.12.0.2..HEAD

__PATCHFILE_FOLLOWS__
diff --git app/code/core/Mage/Catalog/Model/Url.php app/code/core/Mage/Catalog/Model/Url.php
index fa55fc5..a755b46 100644
--- app/code/core/Mage/Catalog/Model/Url.php
+++ app/code/core/Mage/Catalog/Model/Url.php
@@ -609,6 +609,23 @@ class Mage_Catalog_Model_Url
      */
     public function getUnusedPath($storeId, $requestPath, $idPath)
     {
+        $urlKey = '';
+        return $this->getUnusedPathByUrlkey($storeId, $requestPath, $idPath, $urlKey);
+    }
+
+    /**
+     * Get requestPath that was not used yet.
+     *
+     * Will try to get unique path by adding -1 -2 etc. between url_key and optional url_suffix
+     *
+     * @param int $storeId
+     * @param string $requestPath
+     * @param string $idPath
+     * @param string $urlKey
+     * @return string
+     */
+    public function getUnusedPathByUrlkey($storeId, $requestPath, $idPath, $urlKey = '')
+    {
         if (strpos($idPath, 'product') !== false) {
             $suffix = $this->getProductUrlSuffix($storeId);
         } else {
@@ -645,21 +662,22 @@ class Mage_Catalog_Model_Url
             }
             // match request_url abcdef1234(-12)(.html) pattern
             $match = array();
-            $regularExpression = '#^([0-9a-z/-]+?)(-([0-9]+))?('.preg_quote($suffix).')?$#i';
+            $regularExpression = '#(?P<prefix>(.*/)?' . preg_quote($urlKey) . ')(-(?P<increment>[0-9]+))?(?P<suffix>'
+                . preg_quote($suffix) . ')?$#i';
             if (!preg_match($regularExpression, $requestPath, $match)) {
-                return $this->getUnusedPath($storeId, '-', $idPath);
+                return $this->getUnusedPathByUrlkey($storeId, '-', $idPath, $urlKey);
             }
-            $match[1] = $match[1] . '-';
-            $match[4] = isset($match[4]) ? $match[4] : '';
+            $match['prefix'] = $match['prefix'] . '-';
+            $match['suffix'] = isset($match['suffix']) ? $match['suffix'] : '';

             $lastRequestPath = $this->getResource()
-                ->getLastUsedRewriteRequestIncrement($match[1], $match[4], $storeId);
+                ->getLastUsedRewriteRequestIncrement($match['prefix'], $match['suffix'], $storeId);
             if ($lastRequestPath) {
-                $match[3] = $lastRequestPath;
+                $match['increment'] = $lastRequestPath;
             }
-            return $match[1]
-                . (isset($match[3]) ? ($match[3]+1) : '1')
-                . $match[4];
+            return $match['prefix']
+                . (isset($match['increment']) ? ($match['increment']+1) : '1')
+                . $match['suffix'];
         }
         else {
             return $requestPath;
@@ -699,7 +717,7 @@ class Mage_Catalog_Model_Url
     {
         $storeId = $category->getStoreId();
         $idPath  = $this->generatePath('id', null, $category);
-        $suffix  = $this->getCategoryUrlSuffix($storeId);
+        $categoryUrlSuffix = $this->getCategoryUrlSuffix($storeId);

         if (isset($this->_rewrites[$idPath])) {
             $this->_rewrite = $this->_rewrites[$idPath];
@@ -713,27 +731,27 @@ class Mage_Catalog_Model_Url
             $urlKey = $this->getCategoryModel()->formatUrlKey($category->getUrlKey());
         }

-        $categoryUrlSuffix = $this->getCategoryUrlSuffix($category->getStoreId());
         if (null === $parentPath) {
             $parentPath = $this->getResource()->getCategoryParentPath($category);
         }
         elseif ($parentPath == '/') {
             $parentPath = '';
         }
-        $parentPath = Mage::helper('catalog/category')->getCategoryUrlPath($parentPath,
-                                                                           true, $category->getStoreId());
+        $parentPath = Mage::helper('catalog/category')->getCategoryUrlPath($parentPath, true, $storeId);

-        $requestPath = $parentPath . $urlKey . $categoryUrlSuffix;
-        if (isset($existingRequestPath) && $existingRequestPath == $requestPath . $suffix) {
+        $requestPath = $parentPath . $urlKey;
+        $regexp = '/^' . preg_quote($requestPath, '/') . '(\-[0-9]+)?' . preg_quote($categoryUrlSuffix, '/') . '$/i';
+        if (isset($existingRequestPath) && preg_match($regexp, $existingRequestPath)) {
             return $existingRequestPath;
         }

-        if ($this->_deleteOldTargetPath($requestPath, $idPath, $storeId)) {
+        $fullPath = $requestPath . $categoryUrlSuffix;
+        if ($this->_deleteOldTargetPath($fullPath, $idPath, $storeId)) {
             return $requestPath;
         }

-        return $this->getUnusedPath($category->getStoreId(), $requestPath,
-                                    $this->generatePath('id', null, $category)
+        return $this->getUnusedPathByUrlkey($storeId, $fullPath,
+            $this->generatePath('id', null, $category), $urlKey
         );
     }

@@ -798,7 +816,8 @@ class Mage_Catalog_Model_Url
             $this->_rewrite = $this->_rewrites[$idPath];
             $existingRequestPath = $this->_rewrites[$idPath]->getRequestPath();

-            if ($existingRequestPath == $requestPath . $suffix) {
+            $regexp = '/^' . preg_quote($requestPath, '/') . '(\-[0-9]+)?' . preg_quote($suffix, '/') . '$/i';
+            if (preg_match($regexp, $existingRequestPath)) {
                 return $existingRequestPath;
             }

@@ -836,7 +855,7 @@ class Mage_Catalog_Model_Url
         /**
          * Use unique path generator
          */
-        return $this->getUnusedPath($storeId, $requestPath.$suffix, $idPath);
+        return $this->getUnusedPathByUrlkey($storeId, $requestPath.$suffix, $idPath, $urlKey);
     }

     /**
@@ -891,8 +910,8 @@ class Mage_Catalog_Model_Url
                 $parentPath = Mage::helper('catalog/category')->getCategoryUrlPath($parentPath,
                     true, $category->getStoreId());

-                return $this->getUnusedPath($category->getStoreId(), $parentPath . $urlKey . $categoryUrlSuffix,
-                    $this->generatePath('id', null, $category)
+                return $this->getUnusedPathByUrlkey($category->getStoreId(), $parentPath . $urlKey . $categoryUrlSuffix,
+                    $this->generatePath('id', null, $category), $urlKey
                 );
             }

@@ -913,14 +932,14 @@ class Mage_Catalog_Model_Url
                 $this->_addCategoryUrlPath($category);
                 $categoryUrl = Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath(),
                     false, $category->getStoreId());
-                return $this->getUnusedPath($category->getStoreId(), $categoryUrl . '/' . $urlKey . $productUrlSuffix,
-                    $this->generatePath('id', $product, $category)
+                return $this->getUnusedPathByUrlkey($category->getStoreId(), $categoryUrl . '/' . $urlKey . $productUrlSuffix,
+                    $this->generatePath('id', $product, $category), $urlKey
                 );
             }

             // for product only
-            return $this->getUnusedPath($category->getStoreId(), $urlKey . $productUrlSuffix,
-                $this->generatePath('id', $product)
+            return $this->getUnusedPathByUrlkey($category->getStoreId(), $urlKey . $productUrlSuffix,
+                $this->generatePath('id', $product), $urlKey
             );
         }

Nếu bạn muốn sử dụng bản vá này với CE, hãy đảm bảo kiểm tra đúng cách, vì nó đã được phát triển cho EE.


Bạn đã tự mình thử bản vá EE này trên CE chưa?
Tyler V.

@TylerV. Không ...
Simon

3
Tôi đã thử bản vá này trong EE 1.9.1.1 và có thể phù hợp với nó hoạt động. Nó khắc phục sự cố với các sản phẩm và danh mục có các phím url giống hệt nhau. Hãy hy vọng họ sớm thực hiện điều này trong một bản phát hành trong tương lai.
Giel Berkers

1
Cảm ơn Simon, chỉ cần tăng từ 1GB lên 3MB trên một trang web của khách hàng ... Phải cắt bớt nó trước mỗi 6 tháng, hy vọng nó sẽ vẫn còn nhỏ bây giờ :)
tóc giả sẽ

1
Tôi vừa thử cái này trên 1.9 CE của tôi và mặc dù nó hoạt động cho các sản phẩm - các danh mục không hoàn toàn đúng. Nếu tôi có một danh mục gọi là 'Thử nghiệm' cung cấp url '... / test' và sau đó tôi tạo một danh mục khác gọi là 'Thử nghiệm' thì nó sẽ cung cấp url '... / test-2' nhưng thay vào đó chỉ cung cấp số không tên: '... / - 2'
lẻ_duck

11

Sau khi bạn áp dụng bản vá được đăng bởi Simon, bạn có thể sử dụng truy vấn sau để xóa dữ liệu rác:

DELETE FROM core_url_rewrite
WHERE is_system <> 1 AND id_path REGEXP "^[0-9]+_[0-9]+$" AND
      (request_path REGEXP ".*-[0-9]*\.html" 
          OR target_path = request_path);

Trái ngược với truy vấn của Ashish Hira, điều này chỉ ảnh hưởng đến các URL có số nguyên như phần cuối - đây là - trong trường hợp của tôi - lý do cho sự lộn xộn.

Nó cố gắng không chạm vào các bản viết lại hợp lệ, ví dụ như có thể đã được tạo khi cập nhật khóa URL.


6

Tôi đã thực hiện câu trả lời được chấp nhận thành công. Trong một cài đặt Magento khác, tôi cần lưu lại một số tùy chỉnh viết lại để tôi xóa tất cả các mục kết thúc bằng một - và sau đó một số dài tới 5 chữ số với:

DELETE FROM `core_url_rewrite` WHERE `request_path` REGEXP '\\-[0-9]{1,5}$';

Điều này chủ yếu hoạt động nhưng tôi vẫn nhận được thêm 2 hàng trên mỗi chỉ mục lại. Không chắc chắn lý do tại sao. Tôi nghĩ rằng tôi sẽ chia sẻ kinh nghiệm này.


1
Bạn có thể đã xóa các URL hợp lệ, nhưng kết thúc bằng một số. Bạn sẽ tìm thấy những người có$collection = Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter('url_key', array('regexp' => '[0-9]$'));
Melvyn

5

Thay đổi cốt lõi mà bạn đề cập dường như chỉ cần thiết nếu bạn có sản phẩm không có url_keys, tuy nhiên Magento phải luôn tạo url_keys cho bạn. Nếu bạn có một số nhà nhập khẩu đang tạo sản phẩm không có url_keys, thì vấn đề này sẽ tăng lên cho các sản phẩm đó. Hãy thử chạy truy vấn sau để tìm các sản phẩm như vậy:

SELECT cpe.entity_id, cpe.sku, cpev.value
FROM catalog_product_entity cpe
LEFT JOIN catalog_product_entity_varchar cpev
ON cpe.entity_id = cpev.entity_id AND cpev.attribute_id = (
    SELECT attribute_id
    FROM eav_attribute
    WHERE `entity_type_id` = 4
    AND `attribute_code` = 'url_key'
)
WHERE cpev.value IS NULL OR cpev.value = ''

Nếu bất kỳ sản phẩm nào trả về từ truy vấn đó, chúng không có url_key và sẽ gặp vấn đề.


2
Lưu ý rằng mặc định entity_type_idcho các sản phẩm là 4 chứ không phải 10.
Simon

3

Tôi đã làm theo giải pháp được phê duyệt để ngăn việc viết lại URL trùng lặp, sau đó xuất core_url_rewritedưới dạng tệp CSV. Đã có thể mở CSV này và xóa tất cả nhưng viết lại URL được tạo thủ công.

Sau đó, tôi đã cắt bớt core_url_rewritebảng và nhập CSV đã lưu của mình bằng cách viết lại URL được tạo thủ công.

Sau tất cả các thay đổi, đã chuyển từ 940K hàng lên 32K. Cải thiện rất lớn.


3

Đây là bản vá (viết lại cục bộ) cho Cộng đồng Magento để sửa lỗi https://github.com/biotech/Magento-URL-Rewrite Trên thực tế cũng giống như bản vá EE PATCH_SUPEE-389_EE_1.12.0.2_v2.sh - kiểm tra mỗi lần viết lại và tránh tạo hồ sơ trùng lặp. Hoạt động tốt 2 tháng qua khi sản xuất CE 1.9, sản phẩm 15k, 4 cửa hàng, tái lập chỉ mục đầy đủ mỗi đêm sau khi thay đổi nhập khẩu sản phẩm số lượng lớn.


Làm thế nào triệt để điều này đã được thử nghiệm? Có vẻ như nó đã được đăng cách đây một giờ ....
SR_Magento

Điều này đã được sửa trong 1.9.2.x, vì vậy chúng tôi không còn phải lo lắng về sự phình to của bảng?
Phòng thí nghiệm Fiasco

Câu trả lời liên kết đơn không phải là câu trả lời tốt nhất ngay cả khi chúng có thể giải quyết vấn đề. Hãy giải thích một chút những gì mã của bạn làm.
Marius

@FiascoLabs có, hoạt động tốt trên tất cả CE 1.9.x
FireBear

1
@FiascoLabs: 1.9.2.x vẫn có vấn đề "viết lại phình to" này và không bao gồm sửa lỗi này, tuy nhiên, như FireBear cho biết, bản vá EE sẽ hoạt động với CE 1.9.2.x. (chưa thử cá nhân; chỉ muốn làm rõ rằng 1.9.2.2 chắc chắn vẫn có vấn đề này)
Eric Seastrand

2

Vì điều này chưa được đề cập trong chủ đề này, tôi muốn chia sẻ tin tức tuyệt vời rằng vấn đề này đã được khắc phục trong Magento 1.9.3.9 trở lên. Xem các ghi chú phát hành liên quan :

Magento không còn thực hiện các thao tác ghi không cần thiết trên bảng core_url_rewrite.

Vì vậy, tất cả các bản sửa lỗi cho vấn đề này được đề cập ở đây là không cần thiết khi sử dụng phiên bản Magento lớn hơn hoặc bằng 1.9.3.9. Tôi vẫn đề nghị xóa các giá trị cũ như được mô tả trong câu trả lời của Alex .


1

Chạy truy vấn này

DELETE FROM core_url_rewrite WHERE is_system <> 1 AND id_path REGEXP "^[0-9]+_[0-9]+$";

Điều này chắc chắn sẽ giúp bạn giảm kích thước của core_url_sizebảng bằng cách xóa dữ liệu rác.


Bạn có chắc đây là dữ liệu rác? Tôi nghĩ rằng nó đã xóa cũng viết lại được tạo khi thay đổi khóa URL!
Alex

Kiểm tra regex. điều này có nghĩa là không có id hợp lệ
Asish Hira

Nhưng những ID đó cũng được tạo khi thay đổi khóa URL theo cách thủ công trong phần phụ trợ. Xem thêm câu trả lời của tôi.
Alex

0

Thoát khỏi .html

  1. Không sử dụng hậu tố .html
  2. Đặt trong .htaccess

    ## Redirect all htmls.
    RewriteRule (.+)\.html$ /$1 [L,R=301]
  3. Xóa tất cả các .htmlchuyển hướng:

    DELETE FROM core_url_rewrite WHERE request_path LIKE '%.html'

0

Câu trả lời chính thức là cài đặt SUPEE-389. Đơn giản như thế.

Nó hoạt động hoàn hảo với Magento CE vì họ chia sẻ cùng một đoạn mã trong lĩnh vực này.

Bạn có thể tìm thấy tệp vá tại đây, https: //gist.github.com/piotrekk vitaminki / c348538ca91ba35773be # file- patch_supee-389_ee_1-12-0-2_v2-sh

Chúng tôi đã có vấn đề này và nó đã tạo ra hàng ngàn hàng mới sau mỗi chỉ mục lại URL Danh mục. Bây giờ vấn đề đã biến mất ... ngoại trừ thực tế là chúng ta phải dọn sạch DB.

Kịch bản được cung cấp ở đây có vẻ như là một khởi đầu tốt nhưng nó không phải là một giải pháp hoàn hảo,

php shell / Rewrites_doctor.php --remove_rewrites 4

Xem https://www.atwix.com/magento/d repeatated-product-url-keys-in-community-edition/


-2

Ngoài ra còn có một mô-đun chuyên dụng https://github.com/vladsmirnov/url-rewrites , vì vậy bạn không phải áp dụng lại bản vá sau mỗi lần cập nhật Magento. Mô-đun chứa hai phần: mô-đun thực tế, để ngăn chặn sự trùng lặp từ bây giờ và tập lệnh shell để dọn dẹp cơ sở dữ liệu hiện có.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.